8 Auxiliary Tool User Guide

备注

Want to quickly analyze results, plot data, or perform common data processing tasks after completing a DFT calculation with DSPAW?

dspawpy (Python >= 3.9) is such a tool. It can be called programmatically (see example scripts below) and also provides a command-line interactive program.

After following the tutorial installation instructions, you can use the interactive program by typing dspawpy and pressing Enter in the command line:

 ... loading dspawpy cli ...

 This is the dspawpy command-line interactive tool.  Enjoy!
    ( )
   _| |  ___  _ _      _ _  _   _   _  _ _    _   _
 /'_` |/',__)( '_`\  /'_` )( ) ( ) ( )( '_`\ ( ) ( )
( (_| |\__, \| (_) )( (_| || \_/ \_/ || (_) )| (_) |
 \__,_)(____/| ,__/'`\__,_) \___x___/ | ,__/  \__, |
             | |                      | |    ( )_| |
             (_)                      (_)     \___/

 Version: Installation Path

 ======================================
 |  1: Update
 |  2: structure conversion
 |  3: Volumetric data processing
 |  4: Band structure calculation
 |  5: Density of States (DOS) data processing
 |  6: Joint display of band structure and density of states (DOS)
 |  7: Optical properties data processing
 |  8: NEB (Nudged Elastic Band) transition state calculation data processing
 |  9: phonon calculation data processing
 |  10: aimd ab initio molecular dynamics data processing
 |  11: Polarization data processing
 |  12: ZPE zero-point energy data processing
 |  13: Thermal correction energy of TS
 |
 |  q: Quit
 ======================================
 --> Enter a number and press Enter to select a function:

Highlights:

  • Autocompletion: Works by pressing the Tab key, helping to quickly and correctly enter the required program arguments.

  • Multithreaded lazy loading: Loads modules in the background while waiting for user input, significantly reducing waiting time; loads only necessary modules, minimizing memory usage.

Note:

  • When using on a remote server, the startup time may be longer due to poor disk I/O performance, potentially taking up to half a minute in extreme cases (directly related to the server's current disk I/O performance). If this is unacceptable, please install and use dspawpy on your own computer.

  • After typing dspawpy and pressing Enter, Python will first load built-in modules. Once this is complete, the prompt "... loading dspawpy cli ..." will appear, indicating the second stage (loading third-party dependencies) has begun.

  • After the second stage is completed, a welcome screen will be displayed, indicating that dspwapy has finished the initial loading and has entered the third stage. Subsequently, it will dynamically load the corresponding dependency libraries based on the selected functional modules, thereby minimizing waiting time.

8.1 Installation and Updates

  1. On the HZW machine, dspawpy has been pre-installed. Activate the virtual environment using the following command to start using it:

source /data/hzwtech/profile/dspawpy.env
  1. On other machines, please install dspawpy yourself (choose one of the following two methods):

mamba install dspawpy -c conda-forge
#conda install dspawpy -c conda-forge
  • Or, use pip3 (some operating systems may not have the executable pip3, in which case try pip)

pip
  • pip3 is the package manager that comes with python3.

  • Linux and Mac usually come with Python 3 and pip3.

  • On Windows, open the Microsoft Store, search for Python, and install it.

_images/python_ms_store.png

Then open cmd or powershell to use pip.

pip3 install dspawpy

For information on how to configure pip and conda mirror addresses to speed up the installation process, please refer to https://mirrors.tuna.tsinghua.edu.cn/help/pypi/ and https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/.

If the installation still fails, try the mamba/conda installation method above.

警告

On clusters, due to permission issues, the pip in the public path may not support global installation of Python libraries. You must add the --user option after pip install to install them in your home directory under ~/.local/lib/python3.x/site-packages/, where 3.x represents the Python interpreter version, and x can be any integer between 9 and 13.

Python will prioritize loading dspawpy from the home directory, even if the version in the public environment is newer! Therefore, if you have previously installed dspawpy with --user and have forgotten to manually update the old version in your home directory, even after sourcing the public environment, you will not be able to call the dspawpy in the public environment. Instead, the old version will still be used, leading to some bugs.

Therefore, considering that the HZW cluster automatically updates dspawpy weekly, it is recommended not to install it redundantly in your home directory; delete any existing installations. On other clusters, ensure that you manually update dspawpy in your home directory in a timely manner.

If you prefer not to delete and update the dspawpy in your home directory, you can use the -s option when running your Python scripts to prevent importing dspawpy from your home directory: python -s your-script.py.

Update dspawpy

To update dspawpy if it was installed with mamba/conda, use the following command:

mamba update dspawpy
#conda update dspawpy

If dspawpy was installed via pip:

pip install dspawpy -U # -U for upgrading to the latest version

备注

If pip uses a domestic mirror site, it may fail to upgrade smoothly because the mirror site has not yet synchronized the latest version of dspawpy dspawpy_version. Please use the following command to tell pip to download and install from the official PyPI site:

pip install dspawpy -i https://pypi.org/simple --user -U # -i specifies the download address, --user installs for the current user only, and -U installs the latest version

If you encounter errors related to dspawpy during runtime, first verify that you have correctly imported the latest version of dspawpy and check the installation path:

$ python3 # or python

>>> import dspawpy
>>> dspawpy.__version__ # will output the version number
>>> dspawpy.__file__ # will output the installation path

8.2 structure structure conversion

To read structure information, use the read function; to write structure information to a file, use the write function; for quick structure conversion, use the convert function:

API: read(), write(), convert()
dspawpy.io.structure.convert(infile, si=None, ele=None, ai=None, infmt: str | None = None, task: str = 'scf', outfile: str = 'temp.xyz', outfmt: str | None = None, coords_are_cartesian: bool = True)

convert from infile to outfile.

  • multi -> single, only keep last step

  • crystal -> molecule, will lose lattice info

  • molecule -> crystal, will add a box of twice the maximum xyz

  • pdb, dump may suffer decimal precision loss

参数:
  • infile --

    • h5/json/as/hzw/cif/poscar/cssr/xsf/mcsqs/prismatic/yaml/fleur-inpgen file path

    • If a folder is given, will read {task}.h5/json files

    • If structures are given, will read multiple structures.

  • si (int, list, or str) --

    • Structure index, starting from 1

      • si=1, read the 1st

      • si=[1,2], read the 1st and 2nd

      • si=':', read all

      • si='-3:', read the last 3

    • If empty, for multi-configuration files, all configurations will be read; for single-configuration files, the latest configuration will be read.

    • This parameter is only valid for h5/json files.

  • ele --

    • Element symbol, written as 'H' or ['H','O']

    • If empty, atomic information for all elements will be read.

    • This parameter is only valid for h5/json files.

  • ai --

    • Atom index, starting from 1

    • Usage is the same as si

    • If empty, atomic information for all atoms will be read.

    • This parameter is only valid for h5/json files.

  • infmt --

    • Input structure file type, e.g., 'h5'. If None, the file extension will determine the format.

  • task --

    • Used when datafile is a folder path to locate the internal {task}.h5/json file.

    • Calculation task type, including 'scf', 'relax', 'neb', 'aimd'. Other values will be ignored.

  • outfile --

    • Output filename

  • outfmt --

    • Output structure file type, e.g., 'xyz'. If None, the file extension will determine the format.

  • coords_are_cartesian --

    • Whether to write coordinates in Cartesian form (default: True); otherwise, fractional coordinates will be used.

    • This option is currently only valid for as and json formats.

示例

>>> from dspawpy.io.structure import convert
>>> convert('dspawpy_proj/dspawpy_tests/inputs/supplement/PtH.as', outfile='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.hzw')
==> ...PtH.hzw...

batch test

>>> for readable in ['relax.h5', 'system.json', 'aimd.pdb', 'latestStructure.as', 'CuO.hzw', 'POSCAR']:
...     for writable in ['pdb', 'xyz', 'dump', 'as', 'hzw', 'POSCAR']:
...         convert('dspawpy_proj/dspawpy_tests/inputs/supplement/stru/'+readable, outfile=f"dspawpy_proj/dspawpy_tests/outputs/doctest/{readable.split('.')[0]}.{writable}")
==> ...relax.pdb...
==> ...relax.xyz...
==> ...relax.dump...
==> ...relax.as...
==> ...relax.hzw...
==> ...system.pdb...
==> ...system.xyz...
==> ...system.dump...
==> ...system.as...
==> ...system.hzw...
==> ...aimd.pdb...
==> ...aimd.xyz...
==> ...aimd.dump...
==> ...aimd.as...
==> ...aimd.hzw...
==> ...latestStructure.pdb...
==> ...latestStructure.xyz...
==> ...latestStructure.dump...
==> ...latestStructure.as...
==> ...latestStructure.hzw...
==> ...CuO.pdb...
==> ...CuO.xyz...
==> ...CuO.dump...
==> ...CuO.as...
==> ...CuO.hzw...
==> ...POSCAR.pdb...
==> ...POSCAR.xyz...
==> ...POSCAR.dump...
==> ...POSCAR.as...
==> ...POSCAR.hzw...
dspawpy.io.structure.read(datafile: str | list, si=None, ele=None, ai=None, fmt: str | None = None, task: str | None = 'scf')

Read one or more h5/json files and return a list of pymatgen Structures.

参数:
  • datafile --

    • file paths for h5/json/as/hzw/cif/poscar/cssr/xsf/mcsqs/prismatic/yaml/fleur-inpgen files;

    • If a directory path is given, it can be combined with the task parameter to read the {task}.h5/json files inside

    • If a list of strings is given, it will sequentially read the data and merge them into a list of Structures

  • si (int, list or str) --

    • Configuration number, starting from 1

      • si=1, reads the first configuration

      • si=[1,2], reads the first and second configurations

      • si=':', reads all configurations

      • si='-3:', reads the last three configurations

    • If empty, it reads all configurations for multi-configuration files and the latest configuration for single-configuration files

    • This parameter is only valid for h5/json files

  • ele --

    • Element symbol, format reference: 'H' or ['H','O']

    • If empty, it will read atomic information for all elements

    • This parameter is only valid for h5/json files

  • ai --

    • Atom index, starting from 1

    • Same as si

    • If empty, it will read all atom information

    • This parameter is only valid for h5/json files

  • fmt --

    • File format, including 'as', 'hzw', 'xyz', 'pdb', 'h5', 'json' 6 types, other values will be ignored.

    • If empty, the file type will be determined based on file name conventions.

  • task --

    • Used when datafile is a directory path to find the internal {task}.h5/json file.

    • Determine the task type, including 'scf', 'relax', 'neb', 'aimd' four types, other values will be ignored.

返回:

Structure list

返回类型:

pymatgen_Structures

示例

>>> from dspawpy.io.structure import read

Reads a single file to generate a list of Structures

>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/PtH.as')
>>> len(pymatgen_Structures)
1
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/PtH.hzw')
>>> len(pymatgen_Structures)
1
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/Si2.xyz')
>>> len(pymatgen_Structures)
1
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/aimd.pdb')
>>> len(pymatgen_Structures)
1000
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/2.1/relax.h5')
>>> len(pymatgen_Structures)
3
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/2.1/relax.json')
>>> len(pymatgen_Structures)
3

Note that pymatgen_Structures is a list composed of multiple Structure objects, each corresponding to a structure. If there is only one structure, it will also return a list. Please use pymatgen_Structures[0] to obtain the Structure object.

When datafile is a list, it reads multiple files sequentially and merges them into a Structures list

>>> pymatgen_Structures = read(datafile=['dspawpy_proj/dspawpy_tests/inputs/supplement/aimd1.h5','dspawpy_proj/dspawpy_tests/inputs/supplement/aimd2.h5'])
dspawpy.io.structure.write(structure, filename: str, fmt: str | None = None, coords_are_cartesian: bool = True)

Write information to the structure file

参数:
  • structure -- A pymatgen Structure object

  • filename -- Structure filename

  • fmt --

    • Structure file type, natively supports 'json', 'as', 'hzw', 'pdb', 'xyz', 'dump' six types

  • coords_are_cartesian --

    • Whether to write in Cartesian coordinates, default is True; otherwise write in fractional coordinate format

    • This option is currently only effective for 'as' and 'json' formats

示例

First, read the structure information:

>>> from dspawpy.io.structure import read
>>> s = read('dspawpy_proj/dspawpy_tests/inputs/2.15/01/neb01.h5')
>>> len(s)
17

Writing structure information to a file:

>>> from dspawpy.io.structure import write
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.json', coords_are_cartesian=True)
==> ...PtH.json...
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.as', coords_are_cartesian=True)
==> ...PtH.as...
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.hzw', coords_are_cartesian=True)
==> ...PtH.hzw...

PDB, XYZ, and DUMP file types can write multiple conformations to form a "trajectory." The generated XYZ trajectory files can be opened and visualized using visualization software like OVITO.

>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.pdb', coords_are_cartesian=True)
==> ...PtH.pdb...
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.xyz', coords_are_cartesian=True)
==> ...PtH.xyz...
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.dump', coords_are_cartesian=True)
==> ...PtH.dump...

The recommended format for storing single structure information is as format. If the Structure contains magnetic moment or degree of freedom information, it will be written in the most complete format, such as Fix_x, Fix_y, Fix_z, Mag_x, Mag_y, Mag_z. The default value for degree of freedom information is F, and the default value for magnetic moment is 0.0. You can manually delete this default information from the generated as file as needed. Writing to other types of structure files will ignore magnetic moment and degree of freedom information.

See the 2conversion.py script for conversion:

 1# coding:utf-8
 2from dspawpy.io.structure import convert
 3
 4convert(
 5    infile="dspawpy_proj/dspawpy_tests/inputs/2.1/relax.h5",  # Structure to be converted, if in the current path, you can just write the filename
 6    si=None,  # Select configuration number, if not specified, read all by default
 7    ele=None,  # Filter element symbol, default reads atomic information for all elements
 8    ai=None,  # Filter atomic indices, starting from 1, default to read all atomic information
 9    infmt=None,  # Input structure file type, e.g., 'h5'. If None, it will be matched ambiguously based on the filename rule.
10    task="relax",  # Task type, this parameter is only valid when infile is a folder rather than a filename
11    outfile="dspawpy_proj/dspawpy_tests/outputs/us/relaxed.xyz",  # Structure file name
12    outfmt=None,  # Output structure file type, e.g., 'xyz'. If None, it will be fuzzy matched according to filename rules.
13    coords_are_cartesian=True,  # Written in Cartesian coordinates by default
14)

The rules for setting several key parameters of the convert function are shown in the table below:

dspawpy Supported IO format

infmt (input file format)

infile (Input file name fuzzy match)

outfmt (output file format)

outfile (output filename fuzzy match)

Description

h5

*.h5

X

X

HDF5 files saved after DS-PAW calculations are completed

json

*.json

json

*.json

json files saved after DS-PAW calculations are completed

pdb

*.pdb

pdb

*.pdb

Protein Data Bank

as

*.as

as

*.as

DS-PAW structure file containing atomic coordinates and other information

hzw

*.hzw

hzw

*.hzw

DeviceStudio's default structure file

xyz

*.xyz

xyz

*.xyz

Supports only single conformation of molecular structure when reading, and extended-xyz type trajectory files including unit cell when writing

X

X

dump

*.dump

LAMMPS dump-type trajectory files

X

*.cif*/*.mcif*

cif/mcif

*.cif*/*.mcif*

Crystallographic Information File

X

*POSCAR*/*CONTCAR*/*.vasp/CHGCAR*/LOCPOT*/vasprun*.xml*

poscar

*POSCAR*

VASP files

X

*.cssr*

cssr

*.cssr*

Crystal Structure Standard Representation

X

*.yaml/*.yml

yaml/yml

*.yaml/*.yml

YAML Ain't Markup Language

X

*.xsf*

xsf

*.xsf*

eXtended Structural Format

X

*rndstr.in*/*lat.in*/*bestsqs*

mcsqs

*rndstr.in*/*lat.in*/*bestsqs*

Monte Carlo Special Quasirandom Structure

X

inp*.xml/*.in*/inp_*

fleur-inpgen

*.in*

FLEUR structure file, requires the additional installation of the pymatgen-io-fleur library

X

*.res

res

*.res

ShelX res structure file

X

*.config*/*.pwmat*

pwmat

*.config/*.pwmat

PWmat files

X

X

prismatic

*prismatic*

A file format used for STEM simulations

X

CTRL*

X

X

Stuttgart LMTO-ASA files

备注

  • In the table above, * represents any character, and X indicates unsupported formats.

  • h5, json, pdb, xyz, dump, and CONTCAR formats support trajectory information consisting of multiple structures (common in structure optimization, NEB, or AIMD tasks)

  • The in(out)fmt parameter has higher priority than filename wildcard matching; for example, specifying in(out)fmt='h5' allows any filename, even a.json.

  • When writing structural information in json format, only visualization of NEB chain tasks is supported. See Observing the NEB Chain for details.

  • Structure information from DS-PAW output files such as neb.h5, phonon.h5, phonon.json, neb.json, and wannier.json is currently not readable.

8.3 Volumetric Data Processing

volumetricData Visualization

  • See also 3vis_vol.py:

     1# coding:utf-8
     2from dspawpy.io.write import write_VESTA
     3
     4# Read data file (in h5 or json format), process it, and output to a cube file
     5write_VESTA(
     6    in_filename="dspawpy_proj/dspawpy_tests/inputs/2.2/rho.h5",  # Path to the json or h5 file containing electronic system information
     7    data_type="rho",  # Data type, supported values are "rho", "potential", "elf", "pcharge", "rhoBound"
     8    out_filename="dspawpy_proj/dspawpy_tests/outputs/us/DS-PAW_rho.cube",  # Output file path
     9    gridsize=(10, 10, 10),  # Specifies the interpolation grid size
    10    format="cube",  # Supported formats: cube, vesta, and txt (xyz grid coordinates + values)
    11)
    

    Drag the converted file DS-PAW_rho.cube into the VESTA software to visualize it:

    _images/1-3.png

Differential volumetric data visualization

  • See 3dvol.py:

     1# coding:utf-8
     2from dspawpy.io.write import write_delta_rho_vesta
     3
     4# Read the data file (h5 or json format), process it, and output it to a cube file, which can be directly opened with Vesta and has a small volume
     5write_delta_rho_vesta(
     6    total="dspawpy_proj/dspawpy_tests/inputs/supplement/AB.h5",  # Data file for the system containing all components
     7    individuals=[
     8        "dspawpy_proj/dspawpy_tests/inputs/supplement/A.h5",
     9        "dspawpy_proj/dspawpy_tests/inputs/supplement/B.h5",
    10    ],  # Data files for the system containing each component
    11    output="dspawpy_proj/dspawpy_tests/outputs/us/3delta_rho.cube",  # Output file path
    12)
    

    The above script supports the processing of charge density differences in multi-component systems. As an example using a binary system, it generates the charge density difference file delta_rho.cube from AB.h5, A.h5, and B.h5. This file can be directly opened using VESTA.

Volumetric data plane average

 1# coding:utf-8
 2from dspawpy.plot import average_along_axis
 3
 4axes = [
 5    "2"
 6]  # "0", "1", "2" correspond to the x, y, z axes respectively; select which axes to average along
 7axes_indices = [int(i) for i in axes]
 8for ai in axes_indices:
 9    plt = average_along_axis(
10        datafile="dspawpy_proj/dspawpy_tests/inputs/3.3/scf.h5",  # Data file path
11        task="potential",  # Task name, can be 'rho', 'potential', 'elf', 'pcharge', 'rhoBound'
12        axis=ai,  # Axis along which to plot the potential curve
13        smooth=False,  # Whether to smooth
14        smooth_frac=0.8,  # Smoothing coefficient
15        subtype=None,  # Used to specify the subclass of task data, currently only used for Potential
16        label=f"axis{ai}",  # Legend label
17    )
18if len(axes_indices) > 1:
19    plt.legend()
20
21plt.xlabel("Grid Index")
22plt.ylabel("TotalElectrostaticPotential (eV)")
23plt.savefig("dspawpy_proj/dspawpy_tests/outputs/us/3pot_ave.png", dpi=300)  # Image name

Processing the electrostatic potential file obtained from Section 3.3 of Application Cases yields the following vacuum direction potential function curve:

_images/3pot_ave.png
API: write_VESTA(), write_delta_rho_vesta(), average_along_axis()
  • The write_VESTA function handles the visualization of volumetric data:

    dspawpy.io.write.write_VESTA(in_filename: str, data_type: str, out_filename: str = 'DS-PAW.cube', subtype: str | None = None, format: str | None = 'cube', compact: bool = False, inorm: bool = False, gridsize: Sequence[int] | None = None)

    Read data from a json or h5 file containing electronic system information and write to a VESTA formatted file.

    参数:
    • in_filename -- Path to a json or h5 file containing electronic system information

    • data_type -- Data type, supported values are "rho", "potential", "elf", "pcharge", "rhoBound"

    • out_filename -- Output file path, default "DS-PAW.cube"

    • subtype -- Used to specify the subtype of data_type, default is None, which will read the TotalElectrostaticPotential data of potential

    • format -- Output data format, supports "cube" and "vesta" ("vasp"), default is "cube", case-insensitive

    • compact -- Each data point for each grid is placed on a new line, reducing the file size by decreasing the number of spaces (this does not affect the parsing of VESTA software), default is False

    • inorm -- Whether to normalize the volume data so that the sum is 1, default is False

    • gridsize -- The redefined number of grid points, in the format (ngx, ngy, ngz), default is None, which uses the original number of grid points

    返回:

    VESTA formatted file

    返回类型:

    out_filename

    示例

    >>> from dspawpy.io.write import write_VESTA
    >>> write_VESTA("dspawpy_proj/dspawpy_tests/inputs/2.2/rho.json", "rho", out_filename='dspawpy_proj/dspawpy_tests/outputs/doctest/rho.cube')
    ==> ...rho.cube...
    
    >>> from dspawpy.io.write import write_VESTA
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5",
    ...     data_type="potential",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.cube",
    ...     subtype='TotalElectrostaticPotential', # or 'TotalLocalPotential'
    ...     gridsize=(50,50,50), # all integer, can be larger or less than the original gridsize
    ... )
    Interpolating volumetric data...
    volumetric data interpolated
    ==> ...my_potential.cube...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.8/elf.h5",
    ...     data_type="elf",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/elf.cube",
    ... )
    ==> ...elf.cube...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.h5",
    ...     data_type="pcharge",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge.cube",
    ... )
    ==> ...pcharge.cube...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5",
    ...     data_type="potential",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.vasp",
    ...     subtype='TotalElectrostaticPotential', # or 'TotalLocalPotential'
    ...     gridsize=(50,50,50), # all integer, can be larger or less than the original gridsize
    ... )
    Interpolating volumetric data...
    volumetric data interpolated
    ==> ...my_potential.vasp...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.8/elf.h5",
    ...     data_type="elf",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/elf.vasp",
    ... )
    ==> ...elf.vasp...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.h5",
    ...     data_type="pcharge",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge.vasp",
    ... )
    ==> ...pcharge.vasp...
    
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5",
    ...     data_type="potential",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.txt",
    ...     subtype='TotalElectrostaticPotential', # or 'TotalLocalPotential'
    ...     gridsize=(50,50,50), # all integer, can be larger or less than the original gridsize
    ... )
    Interpolating volumetric data...
    volumetric data interpolated
    ==> ...my_potential.txt...
    >>> with open("dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.txt") as t:
    ...     contents = t.readlines()
    ...     for line in contents[:10]:
    ...         print(line.strip())
    # 2 atoms
    # 50 50 50 grid size
    # x y z value
    0.000 0.000 0.000      0.3279418
    0.055 0.055 0.000     -0.0740864
    0.110 0.110 0.000     -0.8811763
    0.165 0.165 0.000     -2.1283865
    0.220 0.220 0.000     -4.0559145
    0.275 0.275 0.000     -6.8291030
    0.330 0.330 0.000    -10.1550909
    

volumetricData refers to physical quantities that vary with spatial position, such as charge density rho, potential energy function potential, localized charge density elf, partial charge density pcharge, and solvent-bound charge density rhoBound. This data is stored in the volumetricData type in DS-PAW.

  • The write_delta_rho_vesta function is responsible for handling the visualization of differential volumetricData:

    dspawpy.io.write.write_delta_rho_vesta(total: str, individuals: list[str], output: str = 'delta_rho.cube', format: str = 'cube', compact: bool = False, inorm: bool = False, gridsize: Sequence | None = None, data_type: str | None = 'rho', subtype: str | None = None)

    Charge density differential visualization

    DeviceStudio does not currently support large files; it is temporarily written in a format that can be opened with VESTA.

    参数:
    • total -- Path to the total charge density file of the system, can be in h5 or json format

    • individuals -- Paths to the charge density files of each component in the system, can be in h5 or json format

    • output -- Output file path, default "delta_rho.cube"

    • format -- Output data format, supports "cube" and "vasp", default to "cube"

    • compact -- Each data point for each grid is placed on a new line, and the file size is reduced by reducing the number of spaces (this does not affect the parsing by VESTA software), default is False

    • inorm -- Whether to normalize the volume data so that the sum is 1, default is False

    • gridsize -- Redefined grid number, format as (ngx, ngy, ngz), default is None, use the original grid number

    返回:

    A charge density file after the difference of charges (total - individual1 - individual2 - ...)

    返回类型:

    output

    示例

    >>> from dspawpy.io.write import write_delta_rho_vesta
    >>> write_delta_rho_vesta(total='dspawpy_proj/dspawpy_tests/inputs/supplement/AB.h5',
    ...     individuals=['dspawpy_proj/dspawpy_tests/inputs/supplement/A.h5', 'dspawpy_proj/dspawpy_tests/inputs/supplement/B.h5'],
    ...     output='dspawpy_proj/dspawpy_tests/outputs/doctest/delta_rho.cube')
    ==> ...delta_rho.cube...
    
  • The average_along_axis function handles averaging volumetric data along a specific axis:

    dspawpy.plot.average_along_axis(datafile: str = 'potential.h5', task: str = 'potential', axis: int = 2, smooth: bool = False, smooth_frac: float = 0.8, raw: bool = False, subtype: str | None = None, verbose: bool = False, **kwargs)

    Plot the average curve of a physical quantity along a certain axis

    参数:
    • datafile -- Path to an h5 or json file, or a folder containing any of these files, default 'potential.h5'

    • task -- Task type, can be 'rho', 'potential', 'elf', 'pcharge', 'rhoBound'

    • axis -- Along which axis to plot the potential curve, default is 2

    • smooth -- Whether to smooth, default False

    • smooth_frac -- Smoothing coefficient, default 0.8

    • raw -- Whether to return plot data to a CSV file

    • subtype -- Used to specify the task data subtype, default None, representing drawing Potential/TotalElectrostaticPotential

    • **kwargs -- Other parameters, passed to matplotlib.pyplot.plot

    返回:

    Can be passed to other functions for further processing

    返回类型:

    axes

    示例

    >>> from dspawpy.plot import average_along_axis
    

    Read data from the potential.h5 file, plot, and save the original plot data to a CSV file

    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/3.3/rho.h5', task='rho', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rho_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/3.3/rho.json', task='rho', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rho_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5', task='potential', axis=2, smooth=True, smooth_frac=0.8, raw=True)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/potential_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.7/potential.json', task='potential', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/potential_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.8/elf.h5', task='elf', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/elf_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.8/elf.json', task='elf', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/elf_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.h5', task='pcharge', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.json', task='pcharge', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.28/rhoBound.h5', task='rhoBound', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rhoBound_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.28/rhoBound.json', task='rhoBound', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rhoBound_json.png')
    

警告

If you execute the above script by connecting to a remote server via SSH and encounter QT-related error messages, it's possible that the program you are using (e.g., MobaXterm) is incompatible with the QT libraries. You should either switch programs (e.g., VSCode or the system's built-in terminal command line) or add the following code, starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

8.4 band data processing

备注

  1. The script calls get_band_data() to read data, and setting efermi=XX during data reading can shift the energy zero point to the specified value; setting zero_to_efermi=True can shift the energy zero point to the Fermi level in the read file.

  2. When plotting using pymatgen's BSPlotter.get_plot() in the script, you can set zero_to_efermi=True to shift the energy zero to the Fermi level. Due to a critical update in pymatgen on August 17, 2023, which changed the return object of the plotting function from plt to axes, subsequent scripts may become incompatible. Therefore, a conditional statement has been added to handle this in the relevant parts of the user's script.

  3. For two-step band calculations, obtain the accurate Fermi level from the first-step self-consistent calculation (from the self-consistent system.json). If this fails, users can modify the energy zero point when calling get_band_data to read data, using the efermi parameter. For example: band_data=get_band_data('band.h5',efermi=-1.5)

  4. When plotting, the script calls BSPlotter.get_plot from pymatgen. When the system is determined to be non-metallic, setting zero_to_efermi will consider the VBM as the Fermi level energy, rather than the Fermi level from the data file. Therefore, when the system is non-metallic, setting zero_to_efermi=True during data reading and setting zero_to_efermi=True during plotting will result in different plots.

Running the Python script listed in this section, the program will determine whether the system is metallic. If it is a non-metallic system, you will be prompted to choose whether to shift the Fermi level to the zero energy point; please follow the prompts.

Conventional Band Treatment

See 4bandplot.py:

 1# coding:utf-8
 2import os
 3import matplotlib.pyplot as plt
 4from pymatgen.electronic_structure.plotter import BSPlotter
 5
 6from dspawpy.io.read import get_band_data
 7
 8datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # Specifies the data file path
 9band_data = get_band_data(
10    band_dir=datafile,
11    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
12    efermi=None,  # Used for manually correcting the Fermi level
13    zero_to_efermi=True,  # For non-metallic systems, the zero point energy should be shifted to the Fermi level
14)
15
16bsp = BSPlotter(band_data)
17axes_or_plt = bsp.get_plot(
18    zero_to_efermi=False,  # The data has already been shifted when read, so this should be turned off
19    ylim=[-10, 10],  # Range of the y-axis for the band structure plot
20    smooth=False,  # Whether to smooth the band structure plot
21    vbm_cbm_marker=False,  # Whether to mark the valence band maximum and conduction band minimum in the band structure plot
22    smooth_tol=0,  # Threshold for smoothing
23    smooth_k=3,  # Order of the smoothing process
24    smooth_np=100,  # Number of points for smoothing
25)
26
27if isinstance(axes_or_plt, plt.Axes):
28    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
29else:
30    fig = axes_or_plt.gcf()  # older version pymatgen
31
32# Add a reference line for the energy zero point
33for ax in fig.axes:
34    ax.axhline(0, lw=2, ls="-.", color="gray")
35
36figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandplot.png"  # Filename for the output band plot
37os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
38fig.savefig(figname, dpi=300)

备注

For band structure calculations, an accurate Fermi level is required, which is obtained from the self-consistent calculation (from system.json). If the acquisition fails, users can modify the efermi parameter in the get_band_data function.

Executing the code will generate a band structure plot similar to the following:

_images/4bandplot.png

The band is projected onto each element separately, with the size of the data points representing the element's contribution to the orbital.

See 4bandplot_elt.py:

 1# coding:utf-8
 2import os
 3
 4import matplotlib.pyplot as plt
 5import numpy as np
 6from pymatgen.electronic_structure.plotter import BSPlotterProjected
 7
 8from dspawpy.io.read import get_band_data
 9
10datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # Specify the data file path
11band_data = get_band_data(
12    band_dir=datafile,
13    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
14    efermi=None,  # Used to manually adjust the Fermi level
15    zero_to_efermi=True,  # For non-metallic systems, shift the zero-point energy to the Fermi level
16)
17
18bsp = BSPlotterProjected(bs=band_data)  # Initialize the BSPlotterProjected class
19axes_or_plt = bsp.get_elt_projected_plots(
20    zero_to_efermi=False,  # The data has already been shifted when read, so this should be disabled
21    ylim=[-8, 5],  # Set the energy range
22    vbm_cbm_marker=False,  # Whether to mark the conduction band minimum (CBM) and valence band maximum (VBM)
23)
24
25if isinstance(axes_or_plt, plt.Axes):
26    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
27elif np.iterable(axes_or_plt):
28    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
29else:
30    fig = axes_or_plt.gcf()  # older version pymatgen
31
32# Add a reference line for the energy zero point
33for ax in fig.axes:
34    ax.axhline(0, lw=2, ls="-.", color="gray")
35
36figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandplot_elt.png"  # The filename for the output band plot
37os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
38fig.savefig(figname, dpi=300)

备注

  1. To plot projected band structure data, use the BSPlotterProjected module.

  2. Use the get_elt_projected_plots function in the BSPlotterProjected module to plot band diagrams with orbital contributions for each element.

Executing the code will generate band plots similar to the following:

_images/4bandplot_elt.png

警告

If you execute the script above by connecting to a remote server via SSH, and you encounter QT-related error messages, it's possible that the program you're using (such as MobaXterm) is incompatible with the QT libraries. You can either switch to a different program (e.g., VSCode or the system's built-in terminal command line), or add the following code, starting on the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Band projections onto different elements' different orbitals

Refer to 4bandplot_elt_orbit.py:

 1# coding:utf-8
 2import os
 3
 4import matplotlib.pyplot as plt
 5import numpy as np
 6from pymatgen.electronic_structure.plotter import BSPlotterProjected
 7
 8from dspawpy.io.read import get_band_data
 9
10datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # Specify the data file path
11band_data = get_band_data(
12    band_dir=datafile,
13    syst_dir=None,  # path to system.json file, only required when band_dir is a json file
14    efermi=None,  # Used for manually correcting the Fermi level
15    zero_to_efermi=True,  # For non-metallic systems, shift the zero point energy to the Fermi level
16)
17
18bsp = BSPlotterProjected(bs=band_data)  # Initialize the BSPlotterProjected class
19# Select elements and orbitals, create a dictionary
20dict_elem_orbit = {"Mo": ["d"], "S": ["s"]}
21
22axes_or_plt = bsp.get_projected_plots_dots(
23    dictio=dict_elem_orbit,
24    zero_to_efermi=False,  # The data has already been shifted when read, so this should be turned off
25    ylim=[-8, 5],  # Set the energy range
26    vbm_cbm_marker=False,  # Whether to mark the conduction band minimum and valence band maximum
27)
28
29if isinstance(axes_or_plt, plt.Axes):
30    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
31elif np.iterable(axes_or_plt):
32    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
33else:
34    fig = axes_or_plt.gcf()  # older version pymatgen
35
36# Add a reference line for the energy zero point
37for ax in fig.axes:
38    ax.axhline(0, lw=2, ls="-.", color="gray")
39
40figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandplot_elt_orbit.png"  # Filename for the output band plot
41os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
42fig.savefig(figname, dpi=300)

备注

  1. Use the get_projected_plots_dots method in the BSPlotterProjected module, which allows users to customize the band structure plots by specifying elements and orbitals (L) to be plotted.

  2. For example, get_projected_plots_dots({'Mo': ['d'], 'S': ['s']}) plots the d-orbitals of Mo and the s-orbitals of S.

Executing the code will generate a band structure plot similar to the following:

_images/4bandplot_elt_orbit.png

警告

If you execute the above script by connecting to a remote server via SSH, and QT-related error messages appear, it may be due to incompatibility between the program used (e.g., MobaXterm) and the QT library. Either change the program (e.g., VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Projecting band structure onto different atomic orbitals

See 4bandplot_patom_porbit.py:

 1# coding:utf-8
 2import os
 3
 4import matplotlib.pyplot as plt
 5import numpy as np
 6from pymatgen.electronic_structure.plotter import BSPlotterProjected
 7
 8from dspawpy.io.read import get_band_data
 9
10datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # Specify the data file path
11band_data = get_band_data(
12    band_dir=datafile,
13    syst_dir=None,  # path to system.json file, required only when band_dir is a JSON file
14    efermi=None,  # Used to manually adjust the Fermi level
15    zero_to_efermi=True,  # For non-metallic systems, shift the zero point energy to the Fermi level
16)
17
18bsp = BSPlotterProjected(bs=band_data)
19# Specify elements, orbitals, and atomic numbers
20dict_elem_orbit = {"Mo": ["px", "py", "pz"]}
21dict_elem_index = {"Mo": [1]}
22
23axes_or_plt = bsp.get_projected_plots_dots_patom_pmorb(
24    dictio=dict_elem_orbit,  # Specify the element-orbit dictionary
25    dictpa=dict_elem_index,  # Specify the element-atomic number dictionary
26    sum_atoms=None,  # Whether to sum over atoms
27    sum_morbs=None,  # Whether to sum orbitals
28    zero_to_efermi=False,  # Data has already been shifted during reading, should be turned off here
29    ylim=None,  # Set the energy range
30    vbm_cbm_marker=False,  # Whether to mark the conduction band minimum and valence band maximum
31    selected_branches=None,  # Specify the energy band branches to be plotted
32    w_h_size=(12, 8),  # Set image width and height
33    num_column=None,  # Number of images displayed per row
34)
35
36if isinstance(axes_or_plt, plt.Axes):
37    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
38elif np.iterable(axes_or_plt):
39    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
40else:
41    fig = axes_or_plt.gcf()  # older version pymatgen
42
43# Add a reference line for the energy zero point
44for ax in fig.axes:
45    ax.axhline(0, lw=2, ls="-.", color="gray")
46
47figname = " dspawpy_proj/dspawpy_tests/outputs/us/4band_patom_porbit.png"  # Output bandpass figure filename
48os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
49fig.savefig(figname, dpi=300)

备注

  1. The get_projected_plots_dots_patom_pmorb function in the BSPlotterProjected module offers greater flexibility, allowing users to customize the band diagrams for specific atoms and orbitals.

  2. Use dictpa to specify the atom, and dictio to specify the orbitals of that atom.

  3. To superimpose projected components of some atoms or orbitals, specify the sum_atoms or sum_morbs parameters according to the documentation of the get_projected_plots_dots_patom_pmorb function.

警告

  1. If only a single orbital is selected and the orbital name has more than one letter (e.g., px, dxy, dxz), the get_projected_plots_dots_patom_pmorb function will raise an error. See here for details.

Executing the code will generate band diagrams similar to the following:

_images/4band_patom_porbit.png

警告

If you execute the above script by connecting to a remote server via SSH, and you encounter QT-related error messages, it's possible that the program you're using (e.g., MobaXterm) is incompatible with the QT libraries. Either switch to another program (e.g., VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Band unfolding processing

See 4bandunfolding.py:

 1# coding:utf-8
 2import os
 3
 4from dspawpy.plot import plot_bandunfolding
 5
 6plt = plot_bandunfolding(
 7    datafile="dspawpy_proj/dspawpy_tests/inputs/2.22.1/band.h5",  # Read data
 8    ef=None,  # Fermi level, read from the file
 9    de=0.05,  # Band width, default 0.05
10    dele=0.06,  # Band gap, default 0.06
11)
12
13plt.ylim(-15, 10)
14figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandunfolding.png"  # Output band structure plot filename
15os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
16plt.savefig(figname, dpi=300)
17# plt.show()

Executing the code yields a band diagram similar to the following:

_images/4bandunfolding.png

警告

警告

This feature currently does not support setting the Fermi level of non-metallic materials as the zero-energy point (the default is the valence band top as the zero-energy point).

警告

If you execute the above script by connecting to a remote server via SSH and encounter QT-related error messages, it might be due to incompatibility between the program used (such as MobaXterm, etc.) and the QT library. You can either switch programs (e.g., VSCode or the system's built-in terminal) or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

band-compare band structure comparison figure processing

Plotting regular band structure and Wannier band structure on the same figure.

Refer to 4bandcompare.py:

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import BSPlotter
 5
 6from dspawpy.io.read import get_band_data
 7
 8band_data = get_band_data(
 9    band_dir="dspawpy_proj/dspawpy_tests/inputs/2.30/wannier.h5",  # Wannier band file path
10    syst_dir=None,  # system.json file path, only needed when band_dir is a json file
11    efermi=None,  # Used for manually adjusting the Fermi level
12    zero_to_efermi=False,  # Whether to shift zero energy to the Fermi level
13)
14bsp = BSPlotter(bs=band_data)
15band_data = get_band_data(
16    band_dir="dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5",  # Read DFT band structure
17    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
18    efermi=None,  # Used for manually correcting the Fermi level
19    zero_to_efermi=False,  # Whether to shift the zero point energy to the Fermi level
20)
21
22bsp2 = BSPlotter(bs=band_data)
23bsp.add_bs(bsp2._bs)
24axes_or_plt = bsp.get_plot(
25    zero_to_efermi=True,  # Move the zero energy level to the Fermi level
26    ylim=[-10, 10],  # Energy band plot y-axis range
27    smooth=False,  # Whether to smooth the band structure plot
28    vbm_cbm_marker=False,  # Whether to mark the valence band maximum and conduction band minimum in the band structure plot
29    smooth_tol=0,  # Threshold for smoothing
30    smooth_k=3,  # Order of the smoothing process
31    smooth_np=100,  # Number of points for smoothing
32    bs_labels=["wannier interpolated", "DFT"],  # Band structure labels
33)
34
35import matplotlib.pyplot as plt  # noqa: E402
36
37if isinstance(axes_or_plt, plt.Axes):
38    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
39else:
40    fig = axes_or_plt.gcf()  # older version pymatgen
41
42# Add a reference line for the energy zero point
43for ax in fig.axes:
44    ax.axhline(0, lw=2, ls="-.", color="gray")
45
46figname = "dspawpy_proj/dspawpy_tests/outputs/us/4wanierBand.png"  # File name for the output band structure plot
47os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
48fig.savefig(figname, dpi=300)

Executing the code will generate band comparison curves similar to the following:

_images/wannier_band.png
API: get_band_data()
  • The get_band_data function is responsible for reading band structure data as follows:

    dspawpy.io.read.get_band_data(band_dir: str, syst_dir: str | None = None, efermi: float | None = None, zero_to_efermi: bool = False, verbose: bool = False) BandStructureSymmLine

    Reads band structure data from an h5 or json file and constructs a BandStructureSymmLine object.

    参数:
    • band_dir --

      • Path to the band structure file, band.h5 / band.json, or a directory containing band.h5 / band.json

      • Note that wannier.h5 can also be read using this function, but band_dir does not support folder types

    • syst_dir -- Path to system.json, prepared only for auxiliary processing of Wannier data (structure and Fermi level are read from it)

    • efermi -- Fermi level, if the Fermi level in the h5 file is incorrect, it can be specified using this parameter

    • zero_to_efermi -- Whether to shift the Fermi level to 0

    返回类型:

    BandStructureSymmLine

    示例

    >>> from dspawpy.io.read import get_band_data
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5')
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.4/band.h5')
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.4/band.json')
    

    If you want to process Wannier band structures by specifying wannier.json, you need to additionally specify the syst_dir parameter.

    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.30/wannier.h5')
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.30/wannier.json', syst_dir='dspawpy_proj/dspawpy_tests/inputs/2.30/system.json')
    

警告

If you are running the above script by connecting to a remote server via SSH and encounter QT-related error messages, it may be due to incompatibility between the program you are using (such as MobaXterm, etc.) and the QT libraries. You can either switch to another program (such as VSCode or the system's built-in terminal), or add the following code, starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

8.5 DOS Data Processing

Total Density of States

See 5dosplot_total.py:

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import DosPlotter
 5
 6from dspawpy.io.read import get_dos_data
 7from dspawpy.plot import plot_dos
 8
 9dos_data = get_dos_data(
10    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Read projected density of states data
11    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
12)
13dos_plotter = DosPlotter(
14    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
15    stack=False,  # True indicates drawing an area chart
16    sigma=None,  # Gaussian broadening, None indicates no smoothing process
17)
18dos_plotter.add_dos(
19    label="total dos", dos=dos_data
20)  # Set the legend for the density of states plot  # Pass the density of states data
21
22ax = plot_dos(
23    dosplotter=dos_plotter,
24    xlim=[-10, 5],  # Set the energy range
25    ylim=[-15, 15],  # Set the density of states range
26)
27ax.axhline(0, lw=2, ls="-.", color="gray")
28
29filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_total.png"  # File name for the output density of states plot
30os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
31
32fig = ax.get_figure()
33fig.savefig(filename, dpi=300)

备注

  1. Use the get_dos_data function to convert the dos.h5 file obtained from DS-PAW calculations into a format supported by pymatgen.

  2. Use the DosPlotter module to obtain the data from the DS-PAW calculated dos.h5 file.

  3. The DosPlotter function can pass parameters: the stack parameter indicates whether to fill the DOS plots, and zero_at_efermi indicates whether to set the Fermi energy to zero in the DOS plot. Here, stack=False and zero_at_efermi=False are set.

  4. Use add_dos in the DosPlotter module to add the DOS data.

  5. Use the get_plot function in the DosPlotter module to plot the DOS.

Executing the code will generate a density of states plot similar to the following:

_images/5dos_total.png

警告

If you execute the above script by connecting to a remote server via SSH and encounter QT-related error messages, it's likely that the program you're using (such as MobaXterm, etc.) is incompatible with the QT libraries. You can either switch programs (e.g., VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Project Density of States onto different orbitals

See 5dosplot_spd.py:

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import DosPlotter
 5
 6from dspawpy.io.read import get_dos_data
 7from dspawpy.plot import plot_dos
 8
 9dos_data = get_dos_data(
10    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Read projected DOS data
11    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
12)
13dos_plotter = DosPlotter(
14    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
15    stack=False,  # True indicates drawing an area chart
16    sigma=None,  # Gaussian broadening, None indicates no smoothing is applied
17)
18dos_plotter.add_dos_dict(
19    dos_dict=dos_data.get_spd_dos(),
20    key_sort_func=None,  # Orbital projection  # Specifies the sorting function
21)
22ax = plot_dos(
23    dosplotter=dos_plotter,
24    xlim=[-10, 5],  # Set the energy range
25    ylim=None,  # Set the density of states range
26)
27
28ax.axhline(0, lw=2, ls="-.", color="gray")
29
30filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_spd.png"  # Filename of the output density of states plot
31os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
32
33fig = ax.get_figure()
34fig.savefig(filename, dpi=300)

备注

Use the add_dos_dict function in the DosPlotter module to obtain the projected density of states (DOS) data, and then use get_spd_dos to project the information onto spd orbitals.

The code execution will produce a density of states plot similar to the following:

_images/5dos_spd.png

警告

If you encounter QT-related error messages when executing the above script via SSH connection to a remote server, it might be due to incompatibility between the program used (e.g., MobaXterm) and the QT library. Either change the program (e.g., VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Projecting the density of states onto different elements

See also 5dosplot_elt.py:

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import DosPlotter
 5
 6from dspawpy.io.read import get_dos_data
 7from dspawpy.plot import plot_dos
 8
 9dos_data = get_dos_data(
10    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Reads projected DOS data
11    return_dos=False,  # If False, always returns a CompleteDos object (regardless of whether projection was enabled during calculation)
12)
13dos_plotter = DosPlotter(
14    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
15    stack=False,  # True indicates drawing an area chart
16    sigma=None,  # Gaussian broadening, None indicates no smoothing is applied
17)
18dos_plotter.add_dos_dict(
19    dos_dict=dos_data.get_element_dos(),
20    key_sort_func=None,  # Projected DOS for elements  # Specify the sorting function
21)
22
23ax = plot_dos(
24    dosplotter=dos_plotter,
25    xlim=[-10, 5],  # Set the energy range
26    ylim=None,  # Set the density of states range
27)
28ax.axhline(0, lw=2, ls="-.", color="gray")
29
30filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_elt.png"  # Filename for the output density of states plot
31os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
32
33fig = ax.get_figure()
34fig.savefig(filename, dpi=300)

备注

Use the add_dos_dict function in the DosPlotter module to obtain projected density of states data, then use get_element_dos to output the projected information according to different elements.

The code execution will produce a density of states plot similar to the following:

_images/5dos_elt.png

警告

If you encounter QT-related error messages when executing the above script via SSH connection to a remote server, it might be due to incompatibility between the program used (e.g., MobaXterm) and the QT library. Either change the program (e.g., VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Projecting the density of states onto different orbitals of different atoms

See 5dosplot_atom_orbit.py:

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.core import Orbital
 5from pymatgen.electronic_structure.plotter import DosPlotter
 6
 7from dspawpy.io.read import get_dos_data
 8from dspawpy.plot import plot_dos
 9
10dos_data = get_dos_data(
11    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Reads projected density of states data
12    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
13)
14dos_plotter = DosPlotter(
15    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
16    stack=False,  # True indicates drawing an area plot
17    sigma=None,  # Gaussian broadening, None indicates no smoothing treatment
18)
19
20# ! Specify atomic number and orbital
21dict_index_orbit = {0: ["dxy"], 2: ["s"]}
22
23print("Plotting...")
24for index in dict_index_orbit:
25    _os = dict_index_orbit[index]
26    _e = str(dos_data.structure.sites[index].species)
27    for _orb in _os:
28        dos_plotter.add_dos(
29            f"{_e}(atom-{index}) {_orb}",  # label
30            dos_data.get_site_orbital_dos(
31                dos_data.structure[index],
32                getattr(Orbital, _orb),
33            ),
34        )
35
36ax = plot_dos(
37    dosplotter=dos_plotter,
38    xlim=[-10, 5],  # Set the energy range
39    ylim=None,  # Set the density of states range
40)
41ax.axhline(0, lw=2, ls="-.", color="gray")
42
43figname = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_atom_orbit.png"  # Output density of states figure filename
44os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
45
46fig = ax.get_figure()
47fig.savefig(figname, dpi=300)

备注

  1. Use the get_site_orbital_dos function to extract the contribution of a specific atom and specific orbital from the DOS data. dos_data.structure[0], Orbital(4) represents obtaining the density of states for the dxy orbital of the first atom; the index in the get_site_orbital_dos function starts from 0.

  2. Running this script and selecting the element and orbital as prompted will generate the corresponding density of states (DOS) plot.

Executing the code will produce a density of states plot similar to the following:

_images/5dos_atom_orbit.png

警告

If you encounter QT-related error messages when executing the above script via SSH connection to a remote server, it's likely due to incompatibility between the program you're using (e.g., MobaXterm) and the QT library. Either switch to a different program (such as VSCode or the system's built-in terminal command line), or add the following code to your Python script starting from the second line:

import matplotlib
matplotlib.use('agg')

Projecting the density of states onto the split d-orbitals (t2g, eg) of different atoms

See also 5dosplot_t2g_eg.py:

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import DosPlotter
 5
 6from dspawpy.io.read import get_dos_data
 7from dspawpy.plot import plot_dos
 8
 9dos_data = get_dos_data(
10    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Read projected density of states data
11    return_dos=False,  # If False, always returns a CompleteDos object (regardless of whether projection was enabled during calculation)
12)
13dos_plotter = DosPlotter(
14    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
15    stack=False,  # True indicates drawing an area chart
16    sigma=None,  # Gaussian broadening, None indicates no smoothing is applied
17)
18# print(dos_data.structure)
19
20# Specify the atomic number, starting from 0
21ais = [1]
22
23print("Plotting...")
24atom_indices = [int(ai) for ai in ais]
25for atom_index in atom_indices:
26    dos_plotter.add_dos_dict(
27        dos_data.get_site_t2g_eg_resolved_dos(dos_data.structure[atom_index]),
28    )
29
30ax = plot_dos(
31    dosplotter=dos_plotter,
32    xlim=[-10, 5],  # Set the energy range
33    ylim=None,  # Set the density of states range
34)
35ax.axhline(0, lw=2, ls="-.", color="gray")
36
37filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_t2g_eg.png"  # Output density of states plot filename
38os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
39
40fig = ax.get_figure()
41fig.savefig(filename, dpi=300)

备注

  1. Use the get_site_t2g_eg_resolved_dos function to extract the t2g and eg orbital contributions for a specific atom from the DOS data. This retrieves the t2g and eg orbital contributions for the second atom.

  2. Running this script and selecting an atom number as prompted will generate the corresponding density of states plot.

Executing the code will generate a density of states plot similar to the following:

_images/5dos_t2g_eg.png

备注

If the element does not contain d orbitals, a blank image will be drawn.

警告

If you execute the script above by connecting to a remote server via SSH and encounter QT-related error messages, it's likely that the program you are using (such as MobaXterm) is incompatible with the QT library. You can either switch programs (e.g., VSCode or the system's built-in terminal command line) or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

d-centered analysis

Taking the Pb-slab system as an example, a d-band center analysis is performed on Pt atoms:

See 5center_dband.py:

 1# coding:utf-8
 2from dspawpy.io.read import get_dos_data
 3from dspawpy.io.utils import d_band
 4
 5dos_data = get_dos_data(
 6    dos_dir="dspawpy_proj/dspawpy_tests/inputs/supplement/dos.h5",  # Read projected density of states data
 7    return_dos=False,  # If False, always returns a CompleteDos object (regardless of whether projection was enabled during calculation)
 8)
 9for spin in dos_data.densities:
10    print("spin=", spin)
11    c = d_band(spin, dos_data)
12    print(c)

Executing the code yields results similar to the following:

spin=1
-1.785319344084034

备注

Currently, only the d-orbital center averaged over all atoms is supported. Element-resolved, atom-projected, or other orbitals are not supported, nor is the selection of spin direction or energy range.

The get_dos_data function is responsible for processing density of states data:

API: get_dos_data()
dspawpy.io.read.get_dos_data(dos_dir: str, return_dos: bool = False, verbose: bool = False)

Read density of states (DOS) data from an h5 or json file, and construct a CompleteDos or DOS object

参数:
  • dos_dir -- Path to the density of states file, dos.h5 / dos.json, or a folder containing dos.h5 / dos.json

  • return_dos (bool, optional) -- Whether to return the DOS object. If False, a CompleteDos object is returned uniformly (regardless of whether projection was enabled during calculation)

返回类型:

CompleteDos or Dos

示例

>>> from dspawpy.io.read import get_dos_data
>>> dos = get_dos_data(dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5')
>>> dos = get_dos_data(dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5', return_dos=True)

8.6 bandDos: Displaying Band Structure and Density of States Together

Using the Si system from the application tutorial as an example:

Display band structure and density of states in a single figure.

See 6bandDosplot.py:

 1# coding:utf-8
 2import os
 3
 4import numpy as np
 5from matplotlib.axes import Axes
 6from pymatgen.electronic_structure.plotter import BSDOSPlotter
 7
 8from dspawpy.io.read import get_band_data, get_dos_data
 9
10bandfile = "dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5"  # Normal band data
11band_data = get_band_data(
12    band_dir=bandfile,
13    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
14    efermi=None,  # Used for manually correcting the Fermi level
15)
16band_efermi = band_data.efermi
17dosfile = "dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5"  # Density of states data
18dos_data = get_dos_data(
19    dos_dir=dosfile,
20    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
21)
22dos_efermi = dos_data.efermi
23bdp = BSDOSPlotter(
24    bs_projection=None,  # Band structure projection method, None means no projection
25    dos_projection=None,  # Projection method for density of states, None means no projection
26    vb_energy_range=4,  # Valence band energy range
27    cb_energy_range=4,  # Conduction band energy range
28    fixed_cb_energy=False,  # Whether to fix the conduction band energy range
29    egrid_interval=1,  # Energy grid interval
30    font="DejaVu Sans",  # Default is Times New Roman, change to DejaVu Sans to avoid warnings due to missing font on Linux
31    axis_fontsize=20,  # Axis font size
32    tick_fontsize=15,  # Tick label font size
33    legend_fontsize=14,  # Legend font size
34    bs_legend="best",  # Band structure legend position
35    dos_legend="best",  # Density of States legend position
36    rgb_legend=True,  # Use colored legend
37    fig_size=(11, 8.5),  # Figure size
38)
39if band_efermi != dos_efermi:
40    print(f"{band_efermi=:.4f} eV")
41    print(f"{dos_efermi=:.4f} eV")
42    d_efermi = band_efermi - dos_efermi
43
44    print(
45        "! Band and DOS Fermi levels are inconsistent, using DOS Fermi level as reference"
46    )
47    band_data.bands = {spin: v + d_efermi for spin, v in band_data.bands.items()}
48
49    # ! Band and DOS Fermi levels are inconsistent, using Band level as the reference
50    # dos_data.energies -= d_efermi
51
52axes_or_plt = bdp.get_plot(
53    bs=band_data, dos=dos_data
54)  # Pass band data  # Pass density of states data
55
56if isinstance(axes_or_plt, Axes):
57    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
58elif np.iterable(axes_or_plt):
59    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
60else:
61    fig = axes_or_plt.gcf()  # older version pymatgen
62
63filename = "dspawpy_proj/dspawpy_tests/outputs/us/6bandDos.png"  # Filename for the band structure - density of states plot output
64os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
65fig.savefig(filename, dpi=300)
66print("==> Saved", filename)

Executing the code yields a band density of states plot similar to the following:

_images/6bandDos.png

警告

If you are connecting to a remote server via SSH and running the above script, and you encounter QT-related error messages, it's possible that the program you are using (such as MobaXterm) is incompatible with the QT libraries. You should either switch programs (e.g., VSCode or the system's built-in terminal command line) or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Display band structure and projected density of states on a single plot.

See 6bandPdosplot.py:

 1# coding:utf-8
 2import os
 3
 4import numpy as np
 5from matplotlib.axes import Axes
 6from pymatgen.electronic_structure.plotter import BSDOSPlotter
 7
 8from dspawpy.io.read import get_band_data, get_dos_data
 9
10bandfile = "dspawpy_proj/dspawpy_tests/inputs/2.4/band.h5"  # Normal band data
11band_data = get_band_data(
12    band_dir=bandfile,
13    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
14    efermi=None,  # Used for manually correcting the Fermi level
15)
16band_efermi = band_data.efermi
17dosfile = (
18    "dspawpy_proj/dspawpy_tests/inputs/2.6/dos.h5"  # DOS data for projected states
19)
20dos_data = get_dos_data(
21    dos_dir=dosfile,
22    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
23)
24dos_efermi = dos_data.efermi
25bdp = BSDOSPlotter(
26    bs_projection="elements",  # Projection method for band structure, None means no projection
27    dos_projection="elements",  # Project DOS onto elements
28    vb_energy_range=4,  # Valence band energy range
29    cb_energy_range=4,  # Conduction band energy range
30    fixed_cb_energy=False,  # Whether to fix the conduction band energy range
31    egrid_interval=1,  # Energy grid interval
32    font="DejaVu Sans",  # Default is Times New Roman, can be changed to DejaVu Sans to avoid warnings due to font not being installed on Linux
33    axis_fontsize=20,  # Axis font size
34    tick_fontsize=15,  # Tick label font size
35    legend_fontsize=14,  # Legend font size
36    bs_legend="best",  # Band structure legend position
37    dos_legend="best",  # Position of the projected density of states legend
38    rgb_legend=True,  # Use colored legend
39    fig_size=(11, 8.5),  # Figure size
40)
41if band_efermi != dos_efermi:
42    print(f"{band_efermi=:.4f} eV")
43    print(f"{dos_efermi=:.4f} eV")
44    d_efermi = band_efermi - dos_efermi
45
46    print(
47        "! Band and DOS Fermi levels are inconsistent, using DOS Fermi level as reference"
48    )
49    band_data.bands = {spin: v + d_efermi for spin, v in band_data.bands.items()}
50
51    # ! Band and DOS Fermi levels are inconsistent, using Band level as reference
52    # dos_data.energies -= d_efermi
53
54axes_or_plt = bdp.get_plot(
55    bs=band_data,
56    dos=dos_data,
57)  # Pass band structure data  # Pass projected density of states data
58
59if isinstance(axes_or_plt, Axes):
60    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
61elif np.iterable(axes_or_plt):
62    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
63else:
64    fig = axes_or_plt.gcf()  # older version pymatgen
65
66filename = "dspawpy_proj/dspawpy_tests/outputs/us/6bandPdos.png"  # filename for the band structure-projected density of states plot
67os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
68fig.savefig(filename, dpi=300)
69print("==> Saved", filename)

Executing the code yields a band-decomposed density of states plot similar to the following:

_images/6bandPdos.png

警告

  1. Given projected band data, it will be projected along the element by default; given ordinary band data (or if the system contains more than 4 types of elements), it will not be projected and a warning will be output.

  2. Given projected density of states (PDOS) data, projection along elements is also the default. You can switch to projection along orbitals, or no projection at all. For ordinary density of states (DOS) data and without disabling the DOS projection option BSDOSPlotter(dos_projection=None), the pymatgen plotting program will report an error, which is why a 6bandDosplot.py file was specifically prepared, as mentioned above.

警告

If you execute the above script by connecting to a remote server via SSH and encounter QT-related error messages, it's likely due to incompatibility between the program you are using (e.g., MobaXterm) and the QT library. Either switch to a different program (such as VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

8.7 optical data processing

Using the scf.h5 file obtained from a quick start calculation of the optical properties of the Si system as an example (Note: the output file name is the same as the task, task = scf; io.optical = true can calculate optical properties):

Processing the reflectivity data, referring to 7optical.py:

 1# coding:utf-8
 2from dspawpy.plot import plot_optical
 3
 4plot_optical(
 5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.12/scf.h5",
 6    keys=["ExtinctionCoefficient", "Reflectance"],
 7    axes=["X"],  # ["X", "Y", "Z", "XY", "YZ", "ZX"]
 8    prefix="dspawpy_proj/dspawpy_tests/outputs/optical",  # Where to save, if empty, it means the current folder
 9    save=True,  # Whether to save the image with the tool's name, if False, please refer to the script below to save manually
10)
11
12# The above function will plot and save the images of ExtinctionCoefficient and Reflectance separately
13# To plot multiple properties on the same figure, uncomment the following code and set the save parameter above to False
14
15# import os
16# import matplotlib.pyplot as plt
17#
18# plt.tick_params(labelsize=16)
19# plt.tight_layout()
20# filename = "outputs/us/7optical.png"  # Filename for the output optical properties plot
21# os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
22# plt.savefig(filename, dpi=300)

备注

Reflectance is an optical property, and users can modify this keyword to "AbsorptionCoefficient", "ExtinctionCoefficient", or "RefractiveIndex" based on their needs, corresponding to the absorption coefficient, extinction coefficient, and refractive index, respectively.

Executing the code will generate a curve showing the reflectance as a function of energy, similar to the following:

_images/7optical.png
API: plot_optical()
dspawpy.plot.plot_optical(datafile: str = 'optical.h5', keys: List[str] = ['AbsorptionCoefficient', 'ExtinctionCoefficient', 'RefractiveIndex', 'Reflectance'], axes: List[str] = ['X', 'Y', 'Z', 'XY', 'YZ', 'ZX'], raw: bool = False, prefix: str = '', save: bool = True, verbose: bool = False)

After the optical property calculation task is completed, read the data and draw a preview image

optical.h5/optical.json -> optical.png

参数:
  • datafile -- Path to an h5 or json file, or a folder containing any of these files, default 'optical.h5'

  • keys -- One of "AbsorptionCoefficient", "ExtinctionCoefficient", "RefractiveIndex", "Reflectance", default "AbsorptionCoefficient"

  • axes -- Index, default "X", "Y", "Z", "XY", "YZ", "ZX"

  • raw -- Whether to save plot data to CSV

  • prefix -- Folder path to save images, if empty, saves in the current directory

  • save -- Whether to save the image, default is True

示例

Plot and save the plot data to rawoptical.csv

>>> from dspawpy.plot import plot_optical
>>> plot_optical("dspawpy_proj/dspawpy_tests/inputs/2.12/scf.h5", "AbsorptionCoefficient", ['X', 'Y'], prefix='dspawpy_proj/dspawpy_tests/outputs/doctest')
>>> plot_optical("dspawpy_proj/dspawpy_tests/inputs/2.12/optical.json", ["AbsorptionCoefficient"], ['X', 'Y'], prefix='dspawpy_proj/dspawpy_tests/outputs/doctest', raw=True)

警告

If you execute the above script by connecting to a remote server via SSH and encounter QT-related error messages, it is likely that the program you are using (such as MobaXterm, etc.) is incompatible with the QT libraries. You can either switch to another program (such as VSCode or the system's built-in terminal command line) or add the following code to your Python script, starting from the second line:

import matplotlib
matplotlib.use('agg')

8.8 neb data processing

Let's start with a quick introduction using the H diffusion on Pt(100) surface example:

Generating intermediate configurations for input files

  • See 8neb_interpolate_structures.py:

     1# coding:utf-8
     2from dspawpy.diffusion.neb import NEB, write_neb_structures
     3from dspawpy.diffusion.nebtools import write_json_chain
     4from dspawpy.io.structure import read
     5
     6# Read initial configuration
     7init_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/00/structure00.as")[0]
     8# Read final state configuration
     9final_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/04/structure04.as")[0]
    10
    11neb = NEB(
    12    initial_structure=init_struct,  # Initial structure
    13    final_structure=final_struct,  # Final state configuration
    14    nimages=8,  # Total of 8 configurations, including initial and final states
    15)
    16structures = neb.linear_interpolate()  # Linear interpolation
    17# structures = neb.idpp_interpolate()   # IDPP interpolation
    18
    19# Save as structure file to dest path
    20write_neb_structures(
    21    structures=structures,  # Insert interpolated structure chains
    22    coords_are_cartesian=True,  # Whether to save in Cartesian coordinates
    23    fmt="as",  # Save format, supported formats: 'json', 'as', 'hzw', 'pdb', 'xyz', 'dump'
    24    path="dspawpy_proj/dspawpy_tests/outputs/us/8neb_interpolate_structures",  # Save path
    25    prefix="structure",  # File name prefix
    26)
    27
    28# Preview initial structure chain
    29write_json_chain(
    30    preview=True,  # whether to enable preview mode
    31    directory="dspawpy_proj/dspawpy_tests/outputs/us/8neb_interpolate_structures",  # Directory for NEB calculations
    32    step=-1,  # Default to saving the structure chain of the last ion step (latest)
    33    dst="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # Save path
    34)
    35# write_xyz_chain(preview=True, # Whether to run in preview mode
    36#                  directory="dspawpy_proj/dspawpy_tests/outputs/us/8neb_interpolate_structures", # NEB calculation directory
    37#                  step=-1, # Default to saving the structure chain of the last ionic step (latest)
    38#                  dst='dspawpy_proj/dspawpy_tests/outputs/us/8neb' # save path
    39# )
    

备注

  1. Users can modify the number of interpolated points as needed. Setting it to 8 will generate a folder containing 8 structure files, with 6 intermediate configurations.

  2. neb.linear_interpolate is a linear interpolation method. The pbc parameter, when set to True, will lock the search for the shortest diffusion path. It defaults to False to increase user control, because

  3. For example, if the initial fractional coordinate of an atom is 0.2 and the final state is 0.8. When pbc = True, the diffusion path will be forced to be 0.2 -> -0.2. When pbc = False, the user can make the program perform interpolation along the diffusion path 0.2 -> 0.8; if the shortest path is desired, manually change 0.8 to -0.2, thereby ensuring the program completes the initial guess of interpolation according to the user's intent.

Plotting the energy barrier diagram

neb.iniFin = true/false

When neb.iniFin = true/false, you can use the path from the NEB calculation for barrier analysis (ensure that the initial and final state calculation files are in the NEB calculation path):

  • Refer to 8neb_barrier_CubicSpline.py:

     1# coding:utf-8
     2from dspawpy.diffusion.nebtools import plot_barrier
     3
     4directory_of_neb_task = (
     5    "dspawpy_proj/dspawpy_tests/inputs/2.15"  # <-- Please modify to the actual NEB path
     6)
     7
     8# Plotting the energy barrier using CubicSpline interpolation
     9plot_barrier(
    10    directory=directory_of_neb_task,  # path of the neb task
    11    method="CubicSpline",  # Cubic spline interpolation
    12    figname="dspawpy_proj/dspawpy_tests/outputs/us/8neb_barrier_CubicSpline.png",  # Output filename for the energy barrier plot
    13    show=False,  # Whether to display the energy barrier plot
    14)
    

备注

After running the above script, you can obtain a barrier curve similar to the following, with cubic spline interpolation:

_images/neb-barrier_cs.png

For this specific example, the curve will exhibit an undesirable "dip" after cubic spline interpolation, which is inherent to the characteristics of the cubic spline interpolation algorithm.

dspawpy internally calls scipy's interpolation algorithms. Taking the cubic spline interpolation algorithm as an example in the script above, it is defined in the scipy documentation as:

class scipy.interpolate.CubicSpline(x, y, axis=0, bc_type='not-a-knot', extrapolate=None)

The keyword arguments include axis, bc_type, and extrapolate, whose specific meanings can be found in scipy.interpolate.CubicSpline. We can specify the corresponding keyword arguments (axis, bc_type, extrapolate) in the plot_barrier function and pass them to the scipy.interpolate.CubicSpline class for processing.

Here we use the script 8neb_barrier.py to compare the curves plotted by interpolating with three algorithms:

 1# coding:utf-8
 2import os
 3
 4import matplotlib.pyplot as plt
 5
 6from dspawpy.diffusion.nebtools import plot_barrier
 7
 8# Compare the differences in energy barrier curves drawn by different interpolation methods, where show should be set to False
 9# 1. interp1d
10plot_barrier(
11    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",  # path for NEB calculation
12    ri=None,  # Reaction coordinate between the initial structure and the second structure, required when the NEB task only calculated intermediate structures
13    rf=None,  # Reaction coordinate between the last configuration and the second-to-last configuration, when the NEB task only calculated intermediate configurations
14    ei=None,  # Energy of the initial configuration, required when the NEB task only calculated intermediate configurations
15    ef=None,  # Energy of the final configuration, required when the NEB task only calculated intermediate configurations
16    method="interp1d",  # Interpolation method
17    figname=None,  # Name of the output energy barrier plot file
18    show=False,  # Whether to display the energy barrier plot
19    kind="quadratic",  # Parameter of the interpolation method
20)
21# 2. CubicSpline
22plot_barrier(
23    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",
24    method="CubicSpline",
25    figname=None,
26    show=False,
27)
28# 3. pchip
29plot_barrier(
30    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",
31    method="pchip",
32    figname=None,
33    show=False,
34)
35
36filename = "dspawpy_proj/dspawpy_tests/outputs/us/8neb_barrier_comparison.png"  # Filename for the energy barrier plot output
37os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
38plt.savefig(filename, dpi=300)
39# plt.show()
_images/neb-barrier.png

备注

  1. Choosing the appropriate interpolation algorithm is crucial for optimizing the final curve presentation.

  2. In most cases, selecting the pchip (piecewise cubic Hermite interpolating polynomial) monotonic cubic spline interpolation algorithm will achieve good results, and it is also the default interpolation algorithm called.

neb.iniFin = true

When neb.iniFin = true is set, reading the neb.h5/neb.json files generated by the NEB calculation allows for a quick barrier analysis:

  • See 8neb_barrier_CubicSpline.py:

     1# coding:utf-8
     2from dspawpy.diffusion.nebtools import plot_barrier
     3
     4# Plot energy barrier using CubicSpline interpolation
     5plot_barrier(
     6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.15/neb.h5",  # Path to neb.h5
     7    method="CubicSpline",  # Cubic spline interpolation
     8    figname="dspawpy_proj/dspawpy_tests/outputs/us/8neb_barrier_.png",  # Output file name for the energy barrier plot
     9    show=False,  # Whether to display the energy barrier plot
    10)
    

Processing the resulting barrier diagram is consistent with the previously read path.

备注

  1. The energy stored in neb.h5 and neb.json files is TotalEnergy. If you need an accurate barrier value, it is recommended to process it by reading the NEB calculation path (taking TotalEnergy0).

警告

If you are connecting to a remote server via SSH to execute the script above and encounter QT-related error messages, it's possible that the program you are using (e.g., MobaXterm) is incompatible with the QT libraries. Either switch to a different program (such as VSCode or the system's built-in terminal command line), or add the following code starting on the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Processing Data for Transition State Calculations

After NEB calculations, it is generally necessary to plot the energy barrier diagram and check the forces on each interpolated structure to ensure they are below a specified threshold. If the results are abnormal, the force and energy changes of each interpolated structure during the structure optimization process should also be checked to determine if they have truly "converged." These operations require at least three cycles. To simplify the process, we provide an all-in-one summary function summary:

  • Refer to 8neb_check_results.py:

     1# coding:utf-8
     2from dspawpy.diffusion.nebtools import summary
     3
     4# Import the neb calculation directory, a complete folder after neb calculation needs to be provided
     5summary(
     6    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",
     7    show_converge=False,  # Whether to display the convergence plots of energy and force
     8    outdir="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # Path to save convergence plots of energy and forces
     9    figname="dspawpy_proj/dspawpy_tests/outputs/us/8neb/neb_barrier_summary.png",  # Path to save the energy barrier plot
    10)
    11# Additional keyword arguments can be set for plotting the barrier diagram, such as:
    12# summary(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='CubicSpline') # Change to CubicSpline for spline interpolation
    

    备注

    1. This script will print the energies and forces of each structure in a table, plot the energy barrier, and also plot the convergence of energy and forces for intermediate structures.

    2. If neb.iniFin = false, the user must copy the results file of the self-consistent calculation, either scf.h5 or system.json, to the corresponding initial and final state subfolders. Otherwise, the program cannot read the energy and force information of the initial and final states and will exit with an error.

    3. By default, the energy barrier plot is stored in the parent directory of the NEB calculation, and the energy and force convergence plots for each intermediate structure are stored in the respective subfolders.

    Executing the code will generate a table similar to the following, displaying the energy and force information for each NEB configuration:

    Image

    Force (eV/Å)

    Reaction coordinate (Å)

    Energy (eV)

    Delta energy (eV)

    00

    0.1803

    0.0000

    -39637.0984

    0.0000

    01

    0.0263

    0.5428

    -39637.0186

    0.0798

    02

    0.0248

    1.0868

    -39636.8801

    0.2183

    03

    0.2344

    1.5884

    -39636.9984

    0.1000

    04

    0.0141

    2.0892

    -39637.0900

    0.0084

    In addition to the energy barrier diagram, you can also obtain the energy and force convergence curves for each intermediate configuration (taking configuration 02 as an example).

    _images/neb-energy.png

警告

If you execute the above script by connecting to a remote server via SSH and encounter QT-related error messages, it might be due to incompatibility between the program you are using (such as MobaXterm) and the QT library. Either switch to another program (such as VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Observing the NEB Chain

Here, the NEB chain refers to the geometric relationship between the interpolated structures (structure00.as, structure01.as, ...), rather than the changes of a single structure during the optimization process.

  • NEB calculations are computationally expensive, and observing the NEB chain helps to judge the convergence speed of the NEB calculation. Furthermore, after generating intermediate structures via interpolation, previewing the NEB chain is often necessary. These needs can be met using the 8neb_visualize.py script:

 1# coding:utf-8
 2from dspawpy.diffusion.nebtools import write_json_chain, write_xyz_chain
 3
 4# Convert the configuration chain under the NEB calculation path to a JSON format file
 5write_json_chain(
 6    preview=False,  # If the NEB calculation is already completed, preview mode is not required
 7    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",  # NEB calculation directory
 8    step=-1,  # Default to saving the configuration chain of the last ion step (latest)
 9    dst="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # Save path
10    ignorels=False,  # Set to True to ignore latestStructureXX.as files
11)
12
13# Convert the configuration chain in the NEB calculation path to xyz format files
14write_xyz_chain(
15    preview=False,  # If the NEB calculation is already completed, preview mode is not required
16    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",  # NEB calculation directory
17    step=-1,  # Default to saving the configuration chain of the last ionic step (latest)
18    dst="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # Save path
19    ignorels=False,  # Set to True to ignore latestStructureXX.as files
20)

备注

  1. After this script generates the neb_movie*.json files, you can view them by opening the json file via Device Studio --> Simulator --> DS-PAW --> Analysis Plot.

  2. The directory parameter specifies the main path of the NEB calculation; the complete folder after the NEB calculation is finished must be provided.

  3. This script supports processing ongoing (i.e., incomplete) NEB calculation files, allowing users to monitor the trajectory in real time.

  4. The xyz file can be opened and viewed using OVITO software: Open the visualization interface via Device Studio --> Simulator --> OVITO, and then drag and drop the xyz file.

  5. Structure information reading priority: latestStructureXX.as > h5 > json; When ignorels is set to True, it first attempts to read data from h5, and if it fails, it reads from json.

Calculate the inter-configuration distance

  • Refer to this script: 8calc_dist.py:

     1# coding:utf-8
     2from dspawpy.diffusion.nebtools import get_distance
     3from dspawpy.io.structure import read
     4
     5# Please modify the paths of structure01.as and structure02.as structure files according to the actual situation
     6# First read the fractional coordinates, element list, and cell information of the two configurations
     7s1 = read("dspawpy_proj/dspawpy_tests/inputs/2.15/01/structure01.as")[0]
     8s2 = read("dspawpy_proj/dspawpy_tests/inputs/2.15/02/structure02.as")[0]
     9# Calculate the distance between the two configurations, note that this function only accepts fractional coordinates
    10dist = get_distance(
    11    spo1=s1.frac_coords,
    12    spo2=s2.frac_coords,
    13    lat1=s1.lattice.matrix,
    14    lat2=s2.lattice.matrix,
    15)
    16print("The distance between the two configurations is:", dist, "Angstrom")
    

Continued calculation with neb

  • To restart a NEB calculation, refer to 8neb_restart.py:

     1# coding:utf-8
     2import os
     3from shutil import copytree, rmtree
     4
     5from dspawpy.diffusion.nebtools import restart
     6
     7if os.path.isdir("dspawpy_proj/dspawpy_tests/outputs/us/neb4bk"):
     8    rmtree("dspawpy_proj/dspawpy_tests/outputs/us/neb4bk")
     9
    10copytree(
    11    "dspawpy_proj/dspawpy_tests/inputs/2.15",
    12    "dspawpy_proj/dspawpy_tests/outputs/us/neb4bk",
    13)
    14restart(
    15    directory="dspawpy_proj/dspawpy_tests/outputs/us/neb4bk",  # NEB task path
    16    output="dspawpy_proj/dspawpy_tests/outputs/us/8neb_restart",  # Backup destination
    17)
    

    See Continued calculation with neb for details.

Energy and maximum atomic force variation trend during NEB calculation

  • To view plots showing the energy and maximum atomic force trends during the NEB calculation, refer to 8neb_energy_force_curves.py:

    1# coding:utf-8
    2from dspawpy.diffusion.nebtools import monitor_force_energy
    3
    4# Specify the path to the NEB calculation folder; after running, Energies.png and MaxForce.png images will be generated in the specified directory
    5unfinished_neb_folder = "dspawpy_proj/dspawpy_tests/inputs/supplement/neb_unfinished"
    6monitor_force_energy(
    7    directory=unfinished_neb_folder,
    8    outdir="imgs",  # Output image path
    9)
    

    Generates energy and force change trend charts:

    _images/Energies.png
    _images/MaxForce.png
API: write_neb_structures(), plot_barrier(), summary(), get_distance(), write_movie_json(), write_xyz(), restart()
  • The write_neb_structures function is responsible for generating intermediate configurations:

    dspawpy.diffusion.neb.write_neb_structures(structures: list, coords_are_cartesian: bool = True, fmt: str = 'as', path: str = '.', prefix='structure')

    Interpolate and generate intermediate configuration files

    参数:
    • structures -- Structure list

    • coords_are_cartesian -- Is the coordinate Cartesian

    • fmt -- Structure file type, default to "as"

    • path -- Save path

    • prefix -- Filename prefix, default to "structure", which will generate files like structure00.as, structure01.as, ...

    返回:

    Saves the configuration file

    返回类型:

    file

    示例

    First, read the .as file to create a structure object

    >>> from dspawpy.io.structure import read
    >>> init_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/00/structure00.as")[0]
    >>> final_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/04/structure04.as")[0]
    

    Then, interpolate and generate intermediate structure files

    >>> from dspawpy.diffusion.neb import NEB,write_neb_structures
    >>> neb = NEB(init_struct,final_struct,8)
    >>> structures = neb.linear_interpolate()   # Linear interpolation
    

    Interpolated structures can be saved to the neb folder.

    >>> write_neb_structures(structures, path="dspawpy_proj/dspawpy_tests/outputs/doctest/11neb_interpolate_structures")
    ==> ...structure00.as...
    ==> ...structure01.as...
    ==> ...structure02.as...
    ==> ...structure03.as...
    ==> ...structure04.as...
    ==> ...structure05.as...
    ==> ...structure06.as...
    ==> ...structure07.as...
    
  • The plot_barrier function is responsible for plotting the energy barrier diagram:

    dspawpy.diffusion.nebtools.plot_barrier(datafile: str = 'neb.h5', directory: str | None = None, ri: float | None = None, rf: float | None = None, ei: float | None = None, ef: float | None = None, method: str = 'PchipInterpolator', figname: str | None = 'neb_barrier.png', show: bool = True, raw: bool = False, verbose: bool = False, **kwargs)

    Call the scipy.interpolate interpolation algorithm to fit the NEB barrier and plot

    参数:
    • datafile -- Path to neb.h5 or neb.json file

    • directory -- NEB calculation path

    • ri -- Initial reaction coordinate

    • rf -- Final state reaction coordinate

    • ei -- Initial state self-consistent energy

    • ef -- Final state self-consistent energy

    • method (str, optional) -- Interpolation algorithm, default 'PchipInterpolator'

    • figname (str, optional) -- Barrier image name, default 'neb_barrier.png'

    • show (bool, optional) -- Whether to display the interactive interface, default True

    • raw (bool, optional) -- Whether to return plotting data to CSV

    抛出:
    • ImportError -- The specified interpolation algorithm does not exist in scipy.interpolate

    • ValueError -- The parameters passed to the interpolation algorithm do not meet the requirements of the algorithm

    示例

    >>> from dspawpy.diffusion.nebtools import plot_barrier
    >>> import matplotlib.pyplot as plt
    

    Comparing different interpolation algorithms

    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='interp1d', kind=2, figname=None, show=False)
    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='interp1d', kind=3, figname=None, show=False)
    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='CubicSpline', figname=None, show=False)
    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='pchip', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/barrier_comparison.png', show=False)
    ==> ...barrier_comparison.png...
    

    Attempt to read neb.h5 file or neb.json file

    >>> plot_barrier(datafile='dspawpy_proj/dspawpy_tests/inputs/2.15/neb.h5', method='pchip', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/barrier_h5.png', show=False)
    ==> ...barrier_h5.png
    >>> plot_barrier(datafile='dspawpy_proj/dspawpy_tests/inputs/2.15/neb.json', method='pchip', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/barrier_json.png', show=False)
    ==> ...barrier_json.png...
    
  • The summary function is responsible for summarizing the NEB calculation task's documentation:

    dspawpy.diffusion.nebtools.summary(directory: str = '.', raw=False, show_converge=False, outdir: str | None = None, **kwargs)

    Summary of NEB task completion, execute the following steps in order:

      1. Print the forces, reaction coordinates, energy, and energy differences from the initial configuration for each structure

      1. Plot the energy barrier diagram

      1. Plot and save the convergence processes of energy and forces during the structure optimization

    参数:
    • directory -- NEB path, default to the current path

    • raw -- Whether to save the plot data to a CSV file

    • show_converge -- Whether to display energy and force convergence plots of the structural optimization process, default is not displayed

    • outdir -- Path to save the convergence process figure, default to directory

    • **kwargs (dict) -- Parameters passed to plot_barrier

    示例

    >>> from dspawpy.diffusion.nebtools import summary
    >>> directory = 'dspawpy_proj/dspawpy_tests/inputs/2.15' # Path for NEB calculation, default to current path
    >>> summary(directory, show=False, figname='dspawpy_proj/dspawpy_tests/outputs/doctest/neb_barrier.png')
    shape: (5, 5)
    ┌────────────┬─────────────┬──────────┬───────────────┬──────────┐
    │ FolderName ┆ Force(eV/Å) ┆ RC(Å)    ┆ Energy(eV)    ┆ E-E0(eV) │
    ╞════════════╪═════════════╪══════════╪═══════════════╪══════════╡
    │ 00         ┆ 0.180272    ┆ 0.0      ┆ -39637.097656 ┆ 0.0      │
    │ 01         ┆ 0.014094    ┆ 0.542789 ┆ -39637.019531 ┆ 0.079814 │
    │ 02         ┆ 0.026337    ┆ 1.0868   ┆ -39636.878906 ┆ 0.218265 │
    │ 03         ┆ 0.024798    ┆ 1.588367 ┆ -39637.0      ┆ 0.100043 │
    │ 04         ┆ 0.234429    ┆ 2.089212 ┆ -39637.089844 ┆ 0.008414 │
    └────────────┴─────────────┴──────────┴───────────────┴──────────┘
    ==> ...neb_barrier.png...
    ==> ...converge.png...
    ==> ...converge.png...
    ==> ...converge.png...
    
    >>> summary(directory, show=False, figname='dspawpy_proj/dspawpy_tests/outputs/doctest/neb_barrier.png', outdir="dspawpy_proj/dspawpy_tests/outputs/doctest/neb_summary")
    shape: (5, 5)
    ┌────────────┬─────────────┬──────────┬───────────────┬──────────┐
    │ FolderName ┆ Force(eV/Å) ┆ RC(Å)    ┆ Energy(eV)    ┆ E-E0(eV) │
    ╞════════════╪═════════════╪══════════╪═══════════════╪══════════╡
    │ 00         ┆ 0.180272    ┆ 0.0      ┆ -39637.097656 ┆ 0.0      │
    │ 01         ┆ 0.014094    ┆ 0.542789 ┆ -39637.019531 ┆ 0.079814 │
    │ 02         ┆ 0.026337    ┆ 1.0868   ┆ -39636.878906 ┆ 0.218265 │
    │ 03         ┆ 0.024798    ┆ 1.588367 ┆ -39637.0      ┆ 0.100043 │
    │ 04         ┆ 0.234429    ┆ 2.089212 ┆ -39637.089844 ┆ 0.008414 │
    └────────────┴─────────────┴──────────┴───────────────┴──────────┘
    ==> ...neb_barrier.png...
    ==> ...converge.png...
    ==> ...converge.png...
    ==> ...converge.png...
    

    If inifin=False, the user must place a converged scf.h5 or system.json in the initial and final state subfolders.

  • The get_distance function calculates the distance between two configurations:

    dspawpy.diffusion.nebtools.get_distance(spo1, spo2, lat1, lat2)

    Calculate the distance between two structures based on their fractional coordinates and cell parameters

    参数:
    • spo1 (np.ndarray) -- Scores coordinate list 1

    • spo2 (np.ndarray) -- Fractional coordinate list 2

    • lat1 (np.ndarray) -- Cell 1

    • lat2 (np.ndarray) -- Cell 2

    返回:

    Distance

    返回类型:

    float

    示例

    First, read the structure information

    >>> from dspawpy.io.structure import read
    >>> s1 = read('dspawpy_proj/dspawpy_tests/inputs/2.15/01/structure01.as')[0]
    >>> s2 = read('dspawpy_proj/dspawpy_tests/inputs/2.15/02/structure02.as')[0]
    

    Calculate the distance between two configurations

    >>> from dspawpy.diffusion.nebtools import get_distance
    >>> dist = get_distance(s1.frac_coords, s2.frac_coords, s1.lattice.matrix, s2.lattice.matrix)
    >>> print('The distance between the two configurations is:', dist, 'Angstrom')
    The distance between the two configurations is: 0.476972808803491 Angstrom
    
  • The functions write_movie_json and write_xyz can write intermediate configurations to JSON or XYZ files:

  • The restart function is responsible for restarting the NEB calculation:

    dspawpy.diffusion.nebtools.restart(directory: str = '.', output: str = 'bakfile')

    Archive and compress old NEB tasks, and prepare for continuation at the original path

    参数:
    • directory -- Old NEB task path, default current path

    • output -- Backup folder path, default is to create a bakfile folder in the current path for backup; Alternatively, you can specify any path, but it cannot be the same as the current path

    示例

    >>> from dspawpy.diffusion.nebtools import restart
    >>> from shutil import copytree
    >>> copytree('dspawpy_proj/dspawpy_tests/inputs/2.15', 'dspawpy_proj/dspawpy_tests/outputs/doctest/neb4bk2', dirs_exist_ok=True)
    'dspawpy_proj/dspawpy_tests/outputs/doctest/neb4bk2'
    >>> restart(directory='dspawpy_proj/dspawpy_tests/outputs/doctest/neb4bk2', output='dspawpy_proj/dspawpy_tests/outputs/doctest/neb_backup')
    ==> ...neb_backup...
    

    The preparation for the continuation calculation may take a long time to complete, please be patient

  • The monitor_force_energy function is responsible for plotting the energy and force changes during the NEB calculation:

    dspawpy.diffusion.nebtools.monitor_force_energy(directory: str, outdir: str = '.', relative: bool = False)

    Read forces and energies during NEB calculations from xx/DS-PAW.log and plot curves

    No JSON files are output during the calculation, and only force information is present in nebXX.h5 files, so DS-PAW.log must be read.

    Energy matching mode, should hit -40521.972259

    8 LOOP 1:

    # iter | Etot(eV) dE(eV) time # 1 | -35958.655378 -3.595866e+04 47.784 s # 2 | -40069.322436 -4.110667e+03 15.146 s # 3 | -40490.281166 -4.209587e+02 15.114 s # 4 | -40521.972259 -3.169109e+01 17.936 s

    示例

    >>> from dspawpy.diffusion.nebtools import monitor_force_energy
    >>> monitor_force_energy(
    ...     directory="dspawpy_proj/dspawpy_tests/inputs/supplement/neb_unfinished",
    ...     outdir="imgs"
    ... )
    Max Force shape: (57, 4)
    ┌───────────┬───────────┬───────────┬───────────┐
    │ Folder 01 ┆ Folder 02 ┆ Folder 03 ┆ Folder 04 │
    ╞═══════════╪═══════════╪═══════════╪═══════════╡
    │ 23.775228 ┆ 71.547767 ┆ 72.641234 ┆ 24.147289 │
    │ 22.683711 ┆ 68.595607 ┆ 69.704747 ┆ 23.0549   │
    │ 5.624252  ┆ 20.071221 ┆ 20.049429 ┆ 5.567894  │
    │ 5.354774  ┆ 19.631643 ┆ 19.599093 ┆ 5.425462  │
    │ 3.188546  ┆ 9.840143  ┆ 9.748006  ┆ 2.943709  │
    │ …         ┆ …         ┆ …         ┆ …         │
    │ 0.293867  ┆ 0.812679  ┆ 0.920251  ┆ 0.573649  │
    │ 0.27249   ┆ 0.7475    ┆ 0.921836  ┆ 0.540239  │
    │ 0.299767  ┆ 0.360673  ┆ 1.174016  ┆ 0.416171  │
    │ 0.249903  ┆ 0.288985  ┆ 1.169237  ┆ 0.366117  │
    │ 0.204396  ┆ 0.518356  ┆ 0.913792  ┆ 0.300884  │
    └───────────┴───────────┴───────────┴───────────┘
    Energies shape: (57, 4)
    ┌───────────────┬───────────────┬───────────────┬───────────────┐
    │ Folder 01     ┆ Folder 02     ┆ Folder 03     ┆ Folder 04     │
    ╞═══════════════╪═══════════════╪═══════════════╪═══════════════╡
    │ -40448.281556 ┆ -40436.419243 ┆ -40436.084611 ┆ -40447.527434 │
    │ -40448.491374 ┆ -40437.026948 ┆ -40436.685178 ┆ -40447.73947  │
    │ -40451.391617 ┆ -40446.884408 ┆ -40446.613158 ┆ -40450.686918 │
    │ -40451.448662 ┆ -40447.079933 ┆ -40446.803281 ┆ -40450.743777 │
    │ -40452.126865 ┆ -40450.274376 ┆ -40449.978142 ┆ -40451.405157 │
    │ …             ┆ …             ┆ …             ┆ …             │
    │ -40452.620987 ┆ -40452.538682 ┆ -40452.230568 ┆ -40452.056262 │
    │ -40452.621777 ┆ -40452.544298 ┆ -40452.231776 ┆ -40452.055815 │
    │ -40452.620701 ┆ -40452.565649 ┆ -40452.164604 ┆ -40452.035357 │
    │ -40452.621371 ┆ -40452.569113 ┆ -40452.164784 ┆ -40452.037426 │
    │ -40452.622418 ┆ -40452.577864 ┆ -40452.141919 ┆ -40452.037885 │
    └───────────────┴───────────────┴───────────────┴───────────────┘
    ==> ...MaxForce.png...
    ==> ...Energies.png...
    

8.9 Phonon Data Processing

Using the example of a phonon band structure and density of states calculation for MgO, using phonon.h5:

If phonopy is not installed, running the following script will result in the message no module named 'phonopy', but this does not affect the program's normal operation.

Phonon band data processing

 1# coding:utf-8
 2import os
 3
 4from pymatgen.phonon.plotter import PhononBSPlotter
 5
 6from dspawpy.io.read import get_phonon_band_data
 7
 8band_data = get_phonon_band_data(
 9    "dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.h5",
10)  # Read phonon band structure
11bsp = PhononBSPlotter(band_data)
12axes_or_plt = bsp.get_plot(ylim=None, units="thz")  # Y-axis range # Units
13import matplotlib.pyplot as plt  # noqa: E402
14
15if isinstance(axes_or_plt, plt.Axes):
16    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
17elif isinstance(axes_or_plt, tuple):
18    fig = axes_or_plt[0].get_figure()
19else:
20    fig = axes_or_plt.gcf()  # older version pymatgen
21
22filename = "dspawpy_proj/dspawpy_tests/outputs/us/9phonon_bandplot.png"  # File name for the output phonon band plot
23os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
24fig.savefig(filename, dpi=300)

Executing the code yields a phonon band structure curve similar to the following:

_images/phonon-nonac.png

警告

If you encounter QT-related error messages when executing the above script via SSH connection to a remote server, it's likely due to incompatibility between the program used (e.g., MobaXterm) and the QT library. Either change the program (e.g., VSCode or the system's built-in terminal command line), or add the following code to your Python script starting from the second line:

import matplotlib
matplotlib.use('agg')

Phonon Density of States Data Processing

  • Refer to 9phonon_dosplot.py:

     1# coding:utf-8
     2import os
     3
     4from pymatgen.phonon.plotter import PhononDosPlotter
     5
     6from dspawpy.io.read import get_phonon_dos_data
     7
     8dos = get_phonon_dos_data("dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.h5")
     9dp = PhononDosPlotter(
    10    stack=False,  # True indicates drawing an area plot
    11    sigma=None,  # Gaussian blur parameter
    12)
    13dp.add_dos(
    14    label="Phonon", dos=dos
    15)  # Legend  # The phonon density of states to be plotted
    16axes_or_plt = dp.get_plot(
    17    xlim=[0, 20],  # x-axis range
    18    ylim=None,  # y-axis range
    19    units="THz",  # Unit
    20)
    21import matplotlib.pyplot as plt  # noqa: E402
    22
    23if isinstance(axes_or_plt, plt.Axes):
    24    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
    25elif isinstance(axes_or_plt, tuple):
    26    fig = axes_or_plt[0].get_figure()
    27else:
    28    fig = axes_or_plt.gcf()  # older version pymatgen
    29
    30filename = " dspawpy_proj/dspawpy_tests/outputs/us/9phonon_dosplot.png"  # Energy barrier plot output filename
    31os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
    32fig.savefig(filename, dpi=300)
    

    Executing the code yields a phonon density of states curve similar to the following:

_images/9phonon_dosplot.png

警告

If you execute the script above by SSH connection to a remote server and encounter QT-related error messages, it's possible that the program you are using (such as MobaXterm) is incompatible with the QT library. Either change the program (e.g., VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Phonon Thermodynamic Data Processing

Refer to 9phonon_thermal.py:

1# coding:utf-8
2from dspawpy.plot import plot_phonon_thermal
3
4plot_phonon_thermal(
5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.26/phonon.h5",  # phonon.h5 data file path
6    figname="dspawpy_proj/dspawpy_tests/outputs/us/9phonon.png",  # Output phonon thermodynamics figure filename
7    show=False,  # Whether to display the image
8)

Executing the code yields phonon thermodynamic curves similar to the following:

_images/9phonon.png
API: get_phonon_band_data(), get_phonon_dos_data(), plot_phonon_thermal()
  • The get_phonon_band_data function is responsible for reading phonon band data:

    dspawpy.io.read.get_phonon_band_data(phonon_band_dir: str, verbose: bool = False)

    Reads phonon band data from an h5 or json file and constructs a PhononBandStructureSymmLine object

    参数:

    phonon_band_dir -- Path to the band structure file, phonon.h5 / phonon.json, or a folder containing these files

    返回类型:

    PhononBandStructureSymmLine

    示例

    >>> from dspawpy.io.read import get_phonon_band_data
    >>> band_data = get_phonon_band_data("dspawpy_proj/dspawpy_tests/inputs/2.16/phonon.h5") # Read phonon band data
    >>> band_data = get_phonon_band_data("dspawpy_proj/dspawpy_tests/inputs/2.16/phonon.json") # Read phonon band data
    
  • The get_phonon_dos_data function is responsible for reading the phonon density of states:

    dspawpy.io.read.get_phonon_dos_data(phonon_dos_dir: str, verbose: bool = False)

    Reads phonon density of states data from an h5 or json file, constructs a PhononDos object

    参数:

    phonon_dos_dir -- Path to the phonon DOS file, phonon_dos.h5 / phonon_dos.json, or a folder containing these files

    返回类型:

    PhononDos

    示例

    >>> from dspawpy.io.read import get_phonon_dos_data
    >>> phdos = get_phonon_dos_data(phonon_dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.json')
    >>> phdos = get_phonon_dos_data(phonon_dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.h5')
    >>> phdos.frequencies
    array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ,
            1.1,  1.2,  1.3,  1.4,  1.5,  1.6,  1.7,  1.8,  1.9,  2. ,  2.1,
            2.2,  2.3,  2.4,  2.5,  2.6,  2.7,  2.8,  2.9,  3. ,  3.1,  3.2,
            3.3,  3.4,  3.5,  3.6,  3.7,  3.8,  3.9,  4. ,  4.1,  4.2,  4.3,
            4.4,  4.5,  4.6,  4.7,  4.8,  4.9,  5. ,  5.1,  5.2,  5.3,  5.4,
            5.5,  5.6,  5.7,  5.8,  5.9,  6. ,  6.1,  6.2,  6.3,  6.4,  6.5,
            6.6,  6.7,  6.8,  6.9,  7. ,  7.1,  7.2,  7.3,  7.4,  7.5,  7.6,
            7.7,  7.8,  7.9,  8. ,  8.1,  8.2,  8.3,  8.4,  8.5,  8.6,  8.7,
            8.8,  8.9,  9. ,  9.1,  9.2,  9.3,  9.4,  9.5,  9.6,  9.7,  9.8,
            9.9, 10. , 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9,
           11. , 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9, 12. ,
           12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9, 13. , 13.1,
           13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9, 14. , 14.1, 14.2,
           14.3, 14.4, 14.5, 14.6, 14.7, 14.8, 14.9, 15. , 15.1, 15.2, 15.3,
           15.4, 15.5, 15.6, 15.7, 15.8, 15.9, 16. , 16.1, 16.2, 16.3, 16.4,
           16.5, 16.6, 16.7, 16.8, 16.9, 17. , 17.1, 17.2, 17.3, 17.4, 17.5,
           17.6, 17.7, 17.8, 17.9, 18. , 18.1, 18.2, 18.3, 18.4, 18.5, 18.6,
           18.7, 18.8, 18.9, 19. , 19.1, 19.2, 19.3, 19.4, 19.5, 19.6, 19.7,
           19.8, 19.9, 20. ])
    
  • The plot_phonon_thermal function is responsible for plotting phonon thermodynamic properties:

    dspawpy.plot.plot_phonon_thermal(datafile: str = 'phonon.h5', figname: str = 'phonon.png', show: bool = True, raw: bool = False, verbose: bool = False)

    Task completed for phonon thermodynamic calculations, plot curves of relevant physical quantities versus temperature

    phonon.h5/phonon.json -> phonon.png

    参数:
    • datafile -- Path to an h5 or json file or a folder containing any of these files, default 'phonon.h5'

    • figname -- Filename to save the image

    • show -- Whether to pop up an interactive interface

    • raw -- Whether to save the plotting data to rawphonon.csv file

    返回:

    Image path, default 'phonon.png'

    返回类型:

    figname

    示例

    >>> from dspawpy.plot import plot_phonon_thermal
    >>> plot_phonon_thermal('dspawpy_proj/dspawpy_tests/inputs/2.26/phonon.h5', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/phonon_thermal_h5.png', show=False)
    >>> plot_phonon_thermal('dspawpy_proj/dspawpy_tests/inputs/2.26/phonon.json', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/phonon_thermal_json.png', show=False, raw=True)
    

警告

If you execute the above script by connecting to a remote server via SSH and encounter QT-related error messages, it's likely that the program you are using (e.g., MobaXterm) is incompatible with the QT libraries. You can either switch programs (e.g., VSCode or the system's built-in terminal) or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

8.10 aimd molecular dynamics simulation data processing

For a quick start, take the molecular dynamics simulation data of the \(H_{2}O\) molecular system, for example, the aimd.h5 file:

Convert the trajectory file format to .xyz or .dump.

Read data from the HDF5 file output by AIMD and generate trajectory files.

The generated .xyz or .dump files can be dragged and dropped into OVITO for visualization. You can open the OVITO visualization interface through Device Studio --> Simulator --> OVITO, and then drag and drop the .xyz or .dump files into OVITO.

See 10write_aimd_traj.py:

 1# coding:utf-8
 2from dspawpy.io.structure import convert
 3
 4convert(
 5    infile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # Structure to be converted, if in the current path, only the filename can be written
 6    si=None,  # Filter the configuration number, if not specified, read all by default
 7    ele=None,  # Filter element symbol, default reads atomic information for all elements
 8    ai=None,  # Filter atomic indices (starting from 1), default to read all atomic information
 9    outfile="dspawpy_proj/dspawpy_tests/outputs/us/10aimdTraj.xyz",  # Can also generate .dump files (lower precision), currently only supports orthogonal unit cells
10)

Executing the code will generate trajectory files in .xyz and .dump formats, which can be opened with OVITO. For more details on structure file conversion, refer to structure structure conversion

备注

OVITO and dspawpy do not support saving systems with non-orthogonal unit cells as dump files.

Changes in energy, temperature, etc. curves during the dynamics process.

  • Refer to 10check_aimd_conv.py:

     1# coding:utf-8
     2from dspawpy.plot import plot_aimd
     3
     4plot_aimd(
     5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # Data file path
     6    show=False,  # Whether to pop up the image window
     7    figname="dspawpy_proj/dspawpy_tests/outputs/us/10aimd.png",  # Output image file name
     8    flags_str="1 2 3 4 5",  # Select data types
     9)
    10# The meaning of flags_str is as follows
    11# 1. Kinetic energy
    12# 2. Total Energy
    13# 3. Pressure
    14# 4. Temperature
    15# 5. Volume
    

    Executing the code will generate the following combined graph:

    _images/aimd-joined.png

警告

If you execute the above script by SSH connection to a remote server and encounter QT-related error messages, it's possible that the program you are using (such as MobaXterm) is incompatible with the QT libraries. You can either switch programs (for example, VSCode or the system's built-in terminal command line), or add the following code starting from the second line of the Python script:

import matplotlib
matplotlib.use('agg')

Mean Squared Displacement (MSD) Analysis

  • See 10aimd_msd.py:

     1# coding:utf-8
     2from dspawpy.analysis.aimdtools import get_lagtime_msd, plot_msd
     3
     4# If AIMD is not completed in one go, you can assign multiple h5 file paths to the datafile parameter in a list form
     5lagtime, msd = get_lagtime_msd(
     6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # Data file path
     7    select="all",  # Default selects all atoms
     8    msd_type="xyz",  # Default to calculate MSD in the xyz directions
     9    timestep=None,  # Default reads the timestep from the datafile
    10)
    11# Plot the graph using the obtained data and save it
    12plot_msd(
    13    lagtime,  # X-axis coordinate
    14    msd,  # vertical axis
    15    xlim=None,  # Set the display range of the x-axis
    16    ylim=None,  # Set the display range of the y-axis
    17    figname="dspawpy_proj/dspawpy_tests/outputs/us/10MSD.png",  # Output image filename
    18    show=False,  # Whether to pop up the image window
    19    ax=None,  # Optional subplot specification
    20)
    

    Executing the code will generate an image similar to the following:

    _images/10MSD.png

警告

If you execute the above script by SSH connection to a remote server and encounter QT-related error messages, it might be due to incompatibility between the program you're using (like MobaXterm, etc.) and the QT libraries. Either switch to a different program (such as VSCode or the system's built-in terminal), or add the following code starting from the second line of the Python script:

import matplotlib
matplotlib.use('agg')

Root Mean Square Deviation (RMSD) Analysis

  • See 10aimd_rmsd.py:

     1# coding:utf-8
     2from dspawpy.analysis.aimdtools import get_lagtime_rmsd, plot_rmsd
     3
     4# If AIMD is not completed in a single run, you can assign multiple paths of h5 files in list form to the datafile parameter
     5lagtime, rmsd = get_lagtime_rmsd(
     6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",
     7    timestep=None,  # Data file path  # Default reads the time step from the datafile
     8)
     9plot_rmsd(
    10    lagtime,  # Horizontal coordinate
    11    rmsd,  # vertical coordinate
    12    xlim=None,  # Set the display range of the x-axis
    13    ylim=None,  # Set the display range of the y-axis
    14    figname="dspawpy_proj/dspawpy_tests/outputs/us/10RMSD.png",  # Output image filename
    15    show=False,  # Whether to pop up the image window
    16    ax=None,  # Optional subplot specification
    17)
    

    Executing the code will generate an image similar to the following:

    _images/10RMSD.png

警告

If you execute the above script by connecting to a remote server via SSH, and QT-related error messages appear, it may be due to incompatibility between the program used (e.g., MobaXterm) and the QT libraries. Either change the program (such as VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

Analysis of Atomic Pair Distribution Functions or Radial Distribution Functions (RDFs)

  • See 10aimd_rdf.py :

     1# coding:utf-8
     2from dspawpy.analysis.aimdtools import get_rs_rdfs, plot_rdf
     3
     4# If AIMD is not completed in one go, you can assign multiple h5 file paths to the datafile parameter in the form of a list.
     5rs, rdfs = get_rs_rdfs(
     6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # Data file path
     7    ele1="H",  # Central element
     8    ele2="O",  # Target element
     9    rmin=0.0,  # Minimum radius
    10    rmax=10.0,  # Maximum radius
    11    ngrid=1000,  # Number of grid points
    12    sigma=0.1,  # sigma value
    13)
    14plot_rdf(
    15    rs,  # x-axis values
    16    rdfs,  # Vertical coordinate
    17    "H",  # Central element
    18    "O",  # Object element
    19    figname="dspawpy_proj/dspawpy_tests/outputs/us/10RDF.png",  # Image save path
    20    show=False,  # Whether to pop up the image window
    21    ax=None,  # Subplot can be specified
    22)
    

    Executing the code will generate an image similar to the following:

    _images/10RDF.png
  • The statistical calculations involved in this section are complex; please refer to the function API for more details.

API: plot_aimd(), get_lagtime_msd(), plot_msd(), get_rs_rdfs(), plot_rdf(), get_lagtime_rmsd(), plot_rmsd()
  • The plot_aimd function can be used to help check the convergence of key physical quantities during AIMD calculations:

    dspawpy.plot.plot_aimd(datafile: str = 'aimd.h5', show: bool = True, figname: str = 'aimd.png', flags_str: str = '12345', raw: bool = False)

    Plot the convergence process of key physical quantities after the AIMD task completion

    aimd.h5 -> aimd.png

    参数:
    • datafile -- Location of the h5 file. For example, 'aimd.h5' or ['aimd.h5', 'aimd2.h5']

    • show -- Whether to display the interactive interface. Default is False

    • figname -- Path to the saved image. Default 'aimd.h5'

    • flags_str -- Subplot number. 1. Kinetic Energy 2. Total Energy 3. Pressure 4. Temperature 5. Volume

    • raw -- Whether to output plot data to a CSV file

    返回:

    Image path, default 'aimd.png'

    返回类型:

    figname

    示例

    >>> from dspawpy.plot import plot_aimd
    

    Read the contents of the aimd.h5 file, plot the convergence process graphs of kinetic energy, total energy, temperature, and volume, and save the corresponding data to rawaimd_*.csv.

    >>> plot_aimd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', flags_str='1 2 3 4 5', raw=True, show=False, figname="dspawpy_proj/dspawpy_tests/outputs/doctest/aimdconv.png")
    >>> plot_aimd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', flags_str='1 2 3 4 5', show=False, figname="dspawpy_proj/dspawpy_tests/outputs/doctest/aimdconv_json.png")
    
  • The get_* and plot_* functions are responsible for reading key physical quantities from the AIMD calculation process:

    dspawpy.analysis.aimdtools.get_lagtime_msd(datafile: str | List[str], select: str | List[int] = 'all', msd_type: str = 'xyz', timestep: float | None = None)

    Calculate the mean squared displacement at different time steps

    参数:
    • datafile --

      • Path to aimd.h5 or aimd.json files, or a directory containing these files (prioritizes searching for aimd.h5)

      • Written as a list, the data will be read sequentially and merged together

      • For example ['aimd1.h5', 'aimd2.h5', '/data/home/my_aimd_task']

    • select -- Select atomic number or element; atomic numbers start from 0; default is 'all', which calculates all atoms

    • msd_type -- Calculate the type of MSD, options: xyz, xy, xz, yz, x, y, z, default is 'xyz', which calculates all components

    • timestep -- Time interval between adjacent structures, in units of fs, default None, will be read from datafile, if failed, set to 1.0fs; If not None, this value will be used to calculate the time series

    返回:

    • lagtime (np.ndarray) -- Time series

    • result (np.ndarray) -- Mean square displacement sequence

    示例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_msd
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', timestep=0.1)
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5')
    Calculating MSD...
    >>> lagtime
    array([0.000e+00, 1.000e+00, 2.000e+00, ..., 1.997e+03, 1.998e+03,
           1.999e+03])
    >>> msd
    array([0.00000000e+00, 3.75844096e-03, 1.45298732e-02, ...,
           7.98518472e+02, 7.99267490e+02, 7.99992702e+02])
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', select='H')
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', select=[0,1])
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', select=['H','O'])
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', select=0)
    Calculating MSD...
    
    dspawpy.analysis.aimdtools.get_lagtime_rmsd(datafile: str | List[str], timestep: float | None = None)
    参数:
    • datafile --

      • Path to aimd.h5 or aimd.json files, or a directory containing these files (prioritizes searching for aimd.h5).

      • Written as a list, the data will be read sequentially and merged together

      • For example ['aimd1.h5', 'aimd2.h5', '/data/home/my_aimd_task']

    • timestep -- Time interval between adjacent structures, in fs, default None, will be read from datafile, set to 1.0fs if failed; If not None, it will be used to calculate the time series

    返回:

    • lagtime (numpy.ndarray) -- Time series

    • rmsd (numpy.ndarray) -- Root mean square deviation sequence

    示例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_rmsd
    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json')
    Calculating RMSD...
    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', timestep=0.1)
    Calculating RMSD...
    >>> lagtime
    array([0.000e+00, 1.000e-01, 2.000e-01, ..., 1.997e+02, 1.998e+02,
           1.999e+02])
    >>> rmsd
    array([ 0.        ,  0.05321816,  0.09771622, ..., 28.27847679,
           28.28130893, 28.28414224])
    
    dspawpy.analysis.aimdtools.get_rs_rdfs(datafile: str | List[str], ele1: str, ele2: str, rmin: float = 0, rmax: float = 10, ngrid: int = 101, sigma: float = 0)

    Compute the radial distribution function (RDF).

    参数:
    • datafile --

      • Path to aimd.h5 or aimd.json files, or a directory containing these files (prioritizes searching for aimd.h5)

      • Written as a list, the data will be read sequentially and merged together

      • For example ['aimd1.h5', 'aimd2.h5', '/data/home/my_aimd_task']

    • ele1 -- Central element

    • ele2 -- Adjacent elements

    • rmin -- Radial distribution minimum value, default is 0

    • rmax -- Radial distribution maximum value, default is 10

    • ngrid -- Number of grid points in the radial distribution, default is 101

    • sigma -- Smoothing parameter

    返回:

    • r (numpy.ndarray) -- Grid points for the radial distribution

    • rdf (numpy.ndarray) -- Radial distribution function

    示例

    >>> from dspawpy.analysis.aimdtools import get_rs_rdfs
    >>> rs, rdfs = get_rs_rdfs(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5',ele1='H',ele2='O', sigma=1e-6)
    Calculating RDF...
    >>> rs, rdfs = get_rs_rdfs(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5',ele1='H',ele2='O')
    Calculating RDF...
    >>> rdfs
    array([0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.00646866,
           0.01098199, 0.0004777 , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        ])
    
    dspawpy.analysis.aimdtools.plot_msd(lagtime, result, xlim: Sequence | None = None, ylim: Sequence | None = None, figname: str | None = None, show: bool = True, ax=None, **kwargs)

    Compute mean squared displacement (MSD) after the AIMD task is completed

    参数:
    • lagtime (np.ndarray) -- Time series

    • result (np.ndarray) -- Mean squared displacement sequence

    • xlim -- x-axis range, default None, set automatically

    • ylim -- y-axis range, default to None, automatically set

    • figname -- Image name, default to None, do not save the image

    • show -- Whether to display the image, default is True

    • ax -- Used to draw the image on a subplot in matplotlib

    • **kwargs (dict) -- Other parameters, such as line width, color, etc., are passed to plt.plot function

    返回类型:

    Image after MSD analysis

    示例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_msd, plot_msd
    

    Specify the location of the h5 file, use the get_lagtime_msd function to obtain data, and the select parameter selects the nth atom (not by element)

    >>> lagtime, msd = get_lagtime_msd('dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', select=[0])
    Calculating MSD...
    

    Plot the data and save the figure

    >>> plot_msd(lagtime, msd, xlim=[0,800], ylim=[0,1000], figname='dspawpy_proj/dspawpy_tests/outputs/doctest/MSD.png', show=False)
    ==> ...MSD.png
    ...
    
    dspawpy.analysis.aimdtools.plot_rdf(rs, rdfs, ele1: str, ele2: str, xlim: Sequence | None = None, ylim: Sequence | None = None, figname: str | None = None, show: bool = True, ax=None, **kwargs)

    Post-AIMD analysis of rdf and plotting.

    参数:
    • rs (numpy.ndarray) -- Radial distribution grid points

    • rdfs (numpy.ndarray) -- Radial distribution function

    • ele1 -- Center element

    • ele2 -- Adjacent elements

    • xlim -- x-axis range, default to None, i.e., set automatically

    • ylim -- y-axis range, default to None, i.e., automatically set

    • figname -- Image name, default to None, meaning no image is saved

    • show -- Whether to display the image, default to True

    • ax (matplotlib.axes.Axes) -- Axis for plotting, default is None, which means creating a new axis

    • **kwargs (dict) -- Other parameters, such as line width, color, etc., are passed to plt.plot function

    返回类型:

    Image after RDF analysis

    示例

    >>> from dspawpy.analysis.aimdtools import get_rs_rdfs, plot_rdf
    

    First obtain the rs and rdfs data as the x and y axis data

    >>> rs, rdfs = get_rs_rdfs('dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', 'H', 'O', rmax=6)
    Calculating RDF...
    

    Passing x and y data to the plot_rdf function to plot

    >>> plot_rdf(rs, rdfs, 'H','O', xlim=[0, 6], ylim=[0, 0.015],figname='dspawpy_proj/dspawpy_tests/outputs/doctest/RDF.png', show=False)
    ==> ...RDF.png
    
    dspawpy.analysis.aimdtools.plot_rmsd(lagtime, result, xlim: Sequence | None = None, ylim: Sequence | None = None, figname: str | None = None, show: bool = True, ax=None, **kwargs)

    Post-AIMD analysis of RMSD and plotting

    参数:
    • lagtime -- Time series

    • result -- Root mean square deviation sequence

    • xlim -- x-axis range

    • ylim -- y-axis range

    • figname -- Image save path

    • show -- Whether to display the image

    • ax (matplotlib.axes._subplots.AxesSubplot) -- If plotting subplots, pass the subplot object

    • **kwargs (dict) -- Parameters passed to plt.plot

    返回类型:

    Image of RMSD analysis of structures

    示例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_rmsd, plot_rmsd
    

    timestep represents the time step length

    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', timestep=0.1)
    Calculating RMSD...
    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', timestep=0.1)
    Calculating RMSD...
    

    Saving directly as RMSD.png image

    >>> plot_rmsd(lagtime, rmsd, xlim=[0,200], ylim=[0, 30],figname='dspawpy_proj/dspawpy_tests/outputs/doctest/RMSD.png', show=False)
    ==> ...RMSD.png
    ...
    
  • For manual data extraction and processing, refer to:

     1from dspawpy.io.read import get_sinfo
     2from dspawpy.io.structure import read
     3
     4
     5aimd_h5_files = ['aimd1.h5','aimd2.h5','aimd3.h5'] # Extract and merge data sequentially from multiple completed aimd.h5 files
     6
     7# Read data from multiple aimd.h5 files at once and create a list of pymatgen Structures
     8pymatgen_structures = read(datafile=aimd_h5_files)
     9
    10# Or extract the arrays
    11for i, df in enumerate(aimd_h5_files): # Get data from each aimd.h5 file sequentially
    12    Nstep, elements, positions, lattices, D_mag_fix = get_sinfo(df)
    

警告

If you connect to a remote server via SSH and execute the above script, and you encounter QT-related error messages, it's possible that the program you're using (such as MobaXterm) is incompatible with the QT libraries. Either change the program (for example, VSCode or the system's built-in terminal command line), or add the following code, starting on the second line of your Python script:

import matplotlib
matplotlib.use('agg')

8.11 Ferroelectric Polarization Data Processing

For a quick start, take the series of scf.h5 files obtained from ferroelectric calculations on the \(HfO_{2}\) system as an example:

  • See 11Ferri.py:

    1# coding:utf-8
    2from dspawpy.plot import plot_polarization_figure
    3
    4plot_polarization_figure(
    5    directory="dspawpy_proj/dspawpy_tests/inputs/2.20",  # Path for iron polarization calculation
    6    repetition=2,  # Number of times to repeat the data points when plotting
    7    figname="dspawpy_proj/dspawpy_tests/outputs/us/11pol.png",  # Output polarization figure filename
    8    show=False,  # Whether to display the polarization figure
    9)  # --> pol.png
    

    Executing the code will generate the following combined figure:

    _images/11pol.png

    The ferroelectric polarization values for the head and tail configurations can be found below:

    1from dspawpy.plot import plot_polarization_figure
    2
    3python
    4plot_polarization_figure(directory='.', annotation=True, annotation_style=1)  # Displays the ferroelectric polarization values for the initial and final configurations.
    

    The code will generate the following combined plot:

    _images/Ferri-Pola-anno1.png

    Alternatively, a second annotation style can be used:

    1from dspawpy.plot import plot_polarization_figure
    2
    3plot_polarization_figure(directory='.', annotation=True, annotation_style=2)  # Displays the ferroelectric polarization values for the initial and final configurations.
    

    The code will generate the following combined plot:

    _images/Ferri-Pola-anno2.png
API: plot_polarization_figure()
  • The plot_polarization_figure function is responsible for plotting the ferroelectric polarization figure:

    dspawpy.plot.plot_polarization_figure(directory: str, repetition: int = 2, annotation: bool = False, annotation_style: int = 1, show: bool = True, figname: str = 'pol.png', raw: bool = False)

    Plot the polarization results of the iron electrode

    参数:
    • directory -- Main directory for the iron polarization calculation task

    • repetition -- Number of times to repeat drawing along the upper (or lower) direction, default 2

    • annotation -- Whether to display the polarization values of the iron electrodes at the beginning and end configurations, displayed by default

    • show -- Interactive display of the image, default True

    • figname -- Image save path, default 'pol.png'

    • raw -- Whether to save the raw data to a CSV file

    返回:

    axes -- Can be passed to other functions for further processing

    返回类型:

    matplotlib.axes._subplots.AxesSubplot

    示例

    >>> from dspawpy.plot import plot_polarization_figure
    >>> result = plot_polarization_figure(directory='dspawpy_proj/dspawpy_tests/inputs/2.20', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/pol1.png', show=False, annotation=True, annotation_style=1)
    >>> result = plot_polarization_figure(directory='dspawpy_proj/dspawpy_tests/inputs/2.20', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/pol2.png', show=False, annotation=True, annotation_style=2)
    

警告

If you encounter QT-related error messages when executing the above script via SSH connection to a remote server, it may be due to incompatibility between the program used (e.g., MobaXterm) and the QT library. Either change the program (e.g., VSCode or the system's built-in terminal command line), or add the following code starting from the second line of your Python script:

import matplotlib
matplotlib.use('agg')

8.12 Zero-Point Vibrational Energy Data Processing

Taking the frequency.txt file obtained from a quick start \(CO\) system frequency calculation as an example, the zero-point vibrational energy is calculated based on the following formula:

\[ZPE=\sum_{i=1}^{3 N} \frac{h \nu_i}{2}\]

where \(\nu_i\) are the normal mode frequencies, \(h\) is Planck's constant (\(6.626\times10^{-34} J\cdot s\)), and \(N\) is the number of atoms.

  • See 12getZPE.py:

    1# coding:utf-8
    2from dspawpy.io.utils import getZPE
    3
    4# Import the frequency.txt file obtained from frequency calculation
    5getZPE(
    6    fretxt="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt",
    7)
    

    The code execution results will be saved to the ZPE.dat file, and the file content is as follows:

    Data read from D:\quickstart\2.13\frequency.txt
    Frequency (meV)
    284.840038
    
    --> Zero-point energy,  ZPE (eV): 0.142420019
    
API: getZPE()
  • The getZPE function is responsible for calculating the zero-point vibrational energy:

    Some functions are extracted from [ase](https://wiki.fysik.dtu.dk/ase/index.html).

    dspawpy.io.utils.getZPE(fretxt: str = 'frequency.txt')

    Read data from fretxt, calculate ZPE

    The results will also be saved to ZPE_TS.dat.

    参数:

    fretxt -- Path to the file recording frequency information, default to 'frequency.txt' in the current path

    返回:

    Zero-point energy

    返回类型:

    ZPE

    示例

    >>> from dspawpy.io.utils import getZPE
    >>> ZPE=getZPE(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt')
    --> Zero-point energy,  ZPE (eV): 0.1424200165
    

8.13 TS Hot Calibration Energy

Contribution of the entropy change of the adsorbate to the energy

Calculation is based on the following formula:

\[\Delta S_{a d s}\left(0 \rightarrow T, P^0\right)=S_{v i b}=\sum_{i=1}^{3 N}\left[\frac{N_{\mathrm{A}} h \nu_i}{T\left(e^{h \nu_i / k_{\mathrm{B}} T}-1\right)}-R \ln \left(1-e^{-h \nu_i / k_{\mathrm{B}} T}\right)\right]\]

Here, \(\Delta S_{a d s}\) represents the entropy change of the adsorbate, calculated based on the harmonic approximation. \(S_{v i b}\) represents the vibrational entropy. \(\nu_i\) is the normal mode frequency, \(N_A\) is Avogadro's constant (\(6.022\times10^{23} mol^{-1}\)), \(h\) is Planck's constant (\(6.626\times10^{-34} J\cdot s\)), \(k_B\) is the Boltzmann constant (\(1.38\times10^{-23} J\cdot K^{-1}\)), \(R\) is the ideal gas constant (\(8.314 J\cdot mol^{-1}\cdot K^{-1}\)), and \(T\) is the system temperature in units of \(K\).

  • See 13getTSads.py for reference:

    1# coding:utf-8
    2from dspawpy.io.utils import getTSads
    3
    4# Import the frequency.txt file calculated from frequency, temperature can be modified arbitrarily
    5getTSads(
    6    fretxt="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt",
    7    T=298.15,
    8)
    

    The execution result will be saved to the TS.dat file, with the following content:

    Data read from D:\quickstart\2.13\frequency.txt
    Frequency (THz)
    68.873994
    
    --> Entropy contribution,  T*S (eV): 4.7566990201851275e-06
    

Ideal gas entropy contribution to energy

Calculations are based on the following formula:

\[\begin{split}\begin{aligned} S(T, P) & =S\left(T, P^{\circ}\right)-k_{\mathrm{B}} \ln \frac{P}{P^{\circ}} \\ & =S_{\text {trans }}+S_{\text {rot }}+S_{\text {elec }}+S_{\text {vib }}-k_{\mathrm{B}} \ln \frac{P}{P^{\circ}} \end{aligned}\end{split}\]

Where:

\[S_{\text {trans }}=k_{\mathrm{B}}\left\{\ln \left[\left(\frac{2 \pi M k_{\mathrm{B}} T}{h^2}\right)^{3 / 2} \frac{k_{\mathrm{B}} T}{P^{\circ}}\right]+\frac{5}{2}\right\}\]
\[\begin{split}S_{\mathrm{rot}}= \begin{cases}0 & \text {, monatomic } \\ k_{\mathrm{B}}\left[\ln \left(\frac{8 \pi^2 I k_{\mathrm{B}} T}{\sigma h^2}\right)+1\right] & \text {, linear } \\ k_{\mathrm{B}}\left\{\ln \left[\frac{\sqrt{\pi I_A I_{\mathrm{B}} I_{\mathrm{C}}}}{\sigma}\left(\frac{8 \pi^2 k_B T}{h^2}\right)^{3 / 2}\right]+\frac{3}{2}\right\} & \text {, nonlinear }\end{cases}\end{split}\]
\[S_{\text {elec }}=k_{\mathrm{B}} \ln [2 \times(\text { total spin })+1]\]
\[S_{\text {vib }}=k_{\mathrm{B}} \sum_i^{\text {vib DOF }}\left[\frac{\epsilon_i}{k_{\mathrm{B}} T\left(e^{\epsilon_i / k_{\mathrm{B}} T}-1\right)}-\ln \left(1-e^{-\epsilon_i / k_{\mathrm{B}} T}\right)\right]\]

where \(I_A\) to \(I_C\) are the three principal moments of inertia for a non-linear molecule, \(I\) is the degenerate moment of inertia for a linear molecule, and \(\sigma\) is the symmetry number of the molecule. Furthermore, monatomic refers to a monatomic molecule, linear refers to a linear molecule, and nonlinear refers to a non-linear molecule. total spin is the total spin quantum number. vib DOF represents vibrational degrees of freedom.

  • Refer to the 13getTSgas.py script for processing:

     1# coding:utf-8
     2from dspawpy.io.utils import getTSgas
     3
     4# Read elements and coordinates from the calculation result file (json or h5)
     5TSgas = getTSgas(
     6    fretxt="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt",
     7    datafile="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.h5",
     8    potentialenergy=-0.0,
     9    geometry="linear",
    10    symmetrynumber=1,
    11    spin=1,
    12    temperature=298.15,
    13    pressure=101325.0,
    14)
    15print("Entropy contribution, T*S (eV):", TSgas)
    16
    17# If only the frequency.txt file is available, the calculation can be completed by manually specifying the elements and coordinates
    18# TSgas = getTSgas(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt', datafile=None, potentialenergy=-0.0, elements=['H', 'H'], geometry='linear', positions=[[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]], symmetrynumber=1, spin=1, temperature=298.15, pressure=101325.0)
    
API: getTSads(), getTSgas()
  • The getTSads function is responsible for calculating the contribution of adsorbate entropy change to the energy:

    Some functions are extracted from [ase](https://wiki.fysik.dtu.dk/ase/index.html).

    dspawpy.io.utils.getTSads(fretxt: str = 'frequency.txt', T: float = 298.15)

    Read data from fretxt, calculate ZPE and TS

    Will also save the results to TSads.dat

    参数:
    • fretxt -- Path to the file recording frequency information, default 'frequency.txt' in the current path

    • T -- Temperature, unit K, default 298.15

    返回:

    Entropy correction

    返回类型:

    TS

    示例

    >>> from dspawpy.io.utils import getTSads
    >>> TSads=getTSads(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt', T=298.15)
    --> T*S (eV): 4.7566997225177686e-06
    
  • The getTSgas function is responsible for calculating the contribution of ideal gas entropy change to energy:

    Some functions are extracted from [ase](https://wiki.fysik.dtu.dk/ase/index.html).

    dspawpy.io.utils.getTSgas(fretxt='frequency.txt', datafile='.', potentialenergy: float = 0.0, elements=None, geometry='linear', positions=None, symmetrynumber=1, spin=1, temperature=298.15, pressure: float = 101325, verbose: bool = False)

    Energy contribution to entropy under the ideal gas approximation"

    参数:
    • fretxt -- Path to the file recording frequency information, default is 'frequency.txt' in the current path

    • datafile -- Path to the JSON or h5 file or folder containing them, default to the current path; If set to None, the elements and positions parameters must be provided

    • potentialenergy -- Potential energy, unit eV

    • elements -- List of elements, if

    • geometry -- Molecular geometry, monatomic, linear, nonlinear

    • positions -- Atomic coordinates, unit Angstrom

    • symmetrynumber -- Symmetry number

    • spin -- Spin number

    • temperature -- Temperature, unit K

    • pressure -- Pressure, unit Pa

    返回:

    Under the ideal gas approximation, calculates the energy contribution to entropy, in units of eV

    返回类型:

    TSgas

    示例

    >>> from dspawpy.io.utils import getTSgas
    >>> TSgas=getTSgas(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt', datafile='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.h5', potentialenergy=-0.0,  geometry='linear', symmetrynumber=1, spin=1, temperature=298.15, pressure=101325.0)
    --> T*S (eV): 0.8515317035550232
    

8.14 Appendix